CF558E A Simple Task 线段树
Posted bxd123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF558E A Simple Task 线段树相关的知识,希望对你有一定的参考价值。
题意翻译
题目大意: 给定一个长度不超过10^5的字符串(小写英文字母),和不超过50000个操作。
每个操作 L R K 表示给区间[L,R]的字符串排序,K=1为升序,K=0为降序。
最后输出最终的字符串。
给每个数字开一个线段树 如果该数字在pos位置 那么在该数字的线段树的pos 位置+1 (有一点类似权值线段树)
因为一个点不是0就是1 (不可能有两个数字在一个点)开绝对标记即可
每次操作的时候 如果是递增的从小到大遍历数字的线段树即可 每次先找出区间个数 放在最左边即可
更改的代码非常秒 见代码
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define pb push_back #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 typedef pair<int,int>pii; ////////////////////////////////// const int N=1e5+10; int t[30][N<<2],col[30][N<<2],x,y,k,n,m,pos,cnt; char s[N],ans[N]; void up(int pos,int num) t[num][pos]=t[num][pos<<1]+t[num][pos<<1|1]; void build(int l,int r,int pos) if(l==r)t[s[l]-‘a‘+1][pos]=1;return; int m=(l+r)>>1;build(lson);build(rson);rep(i,1,26)up(pos,i); void down(int pos,int num,int m) if(col[num][pos]==-1) t[num][pos<<1]=t[num][pos<<1|1]=0; col[num][pos<<1]=col[num][pos<<1|1]=-1; col[num][pos]=0; else if(col[num][pos]>=1) t[num][pos<<1]=(m-(m>>1)); t[num][pos<<1|1]=(m>>1); col[num][pos<<1]=col[num][pos<<1|1]=1; col[num][pos]=0; int qsum(int L,int R,int num,int l,int r,int pos) int ans=0;if(L<=l&&r<=R)return t[num][pos]; int m=(l+r)>>1;down(pos,num,r-l+1); if(L<=m)ans+=qsum(L,R,num,lson);if(R>m)ans+=qsum(L,R,num,rson); return ans; void upsum(int L,int R,int num,int v,int l,int r,int pos) if(L<=l&&r<=R) if(v) col[num][pos]=1;t[num][pos]=r-l+1; return ; else col[num][pos]=-1;t[num][pos]=0; return; //注意一开始写成col[num][pos]++ wa 烂了 -1会加到0 int m=(l+r)>>1;down(pos,num,r-l+1); if(L<=m)upsum(L,R,num,v,lson);if(R>m)upsum(L,R,num,v,rson); up(pos,num); void seeall(int l,int r,int pos) if(l==r) rep(i,1,26) if(t[i][pos])ans[l]=i+‘a‘-1; break; return ; int m=(l+r)>>1; rep(i,1,26)down(pos,i,r-l+1); seeall(lson);seeall(rson); int main() RII(n,m); RS(s+1); build(1,n,1); while(m--) RIII(x,y,k);pos=x; if(k) rep(i,1,26) cnt=qsum(x,y,i,1,n,1); if(!cnt)continue; upsum(x,y,i,0,1,n,1); upsum(pos,pos+cnt-1,i,1,1,n,1);pos=pos+cnt; else repp(i,26,1) cnt=qsum(x,y,i,1,n,1); if(!cnt)continue; upsum(x,y,i,0,1,n,1); upsum(pos,pos+cnt-1,i,1,1,n,1);pos=pos+cnt; seeall(1,n,1); printf("%s",ans+1); return 0;
以上是关于CF558E A Simple Task 线段树的主要内容,如果未能解决你的问题,请参考以下文章