RE on #6 线段树求条
查看原帖
RE on #6 线段树求条
578029
ivyjiao楼主2024/11/20 10:57
#include<bits/stdc++.h>
#define ls ch[u][0]
#define rs ch[u][1]
using namespace std;
const int N=1e6+1,M=1e7+1;
int n,m,l,r,k,b[M],lz[M],ch[M][2],rt[N],cnt;
char s[N];
void upd(int u,int l,int r){
    if(lz[u]!=-1){
        int mid=l+r>>1;
        b[ls]=lz[u]*(mid-l+1);
        b[rs]=lz[u]*(r-mid);
        lz[ls]=lz[u];
        lz[rs]=lz[u];
        lz[u]=-1;
    }
}
int cov(int u,int l,int r,int L,int R,int k){
    if(!u) u=++cnt;
    if(L<=l&&r<=R){
        b[u]=(r-l+1)*k;
        lz[u]=k;
        return u;
    }
    upd(u,l,r);
    int mid=l+r>>1;
    if(L<=mid) ls=cov(ls,l,mid,L,R,k);
    if(R>mid) rs=cov(rs,mid+1,r,L,R,k);
    b[u]=b[ls]+b[rs];
    return u;
}
int qsum(int u,int l,int r,int L,int R){
    if(L<=l&&r<=R) return b[u];
    upd(u,l,r);
    int mid=l+r>>1,ans=0;
    if(L<=mid) ans+=qsum(ls,l,mid,L,R);
    if(R>mid) ans+=qsum(rs,mid+1,r,L,R);
    return ans;
}
void rev(int u,int l,int r,char k){
    if(b[u]==r-l+1){
        for(int i=l;i<=r;i++) s[i]=k;
        return;
    }
    if(l==r) return;
    upd(u,l,r);
    int mid=l+r>>1;
    if(ls&&b[ls]) rev(ls,l,mid,k);
    if(rs&&b[rs]) rev(rs,mid+1,r,k);
}
int main(){
    cin>>n>>m;
    scanf("%s",s+1);
    memset(lz,-1,sizeof lz);
    for(int i=0;i<26;i++) rt[i]=++cnt;
    for(int i=1;i<=n;i++) cov(rt[s[i]-'a'],1,n,i,i,1);
    while(m--){
        cin>>l>>r>>k;
        int p=0;
		if(k==1){
			for(int i=0;i<26;i++){
				int sum=qsum(rt[i],1,n,l,r);
				if(!sum) continue;
				cov(rt[i],1,n,l,r,0);
				cov(rt[i],1,n,l+p,l+p+sum-1,1);
				p+=sum;
			}
		}
        else{
			for(int i=25;i>=0;i--){
				int sum=qsum(rt[i],1,n,l,r);
				if(!sum) continue;
				cov(rt[i],1,n,l,r,0);
				cov(rt[i],1,n,l+p,l+p+sum-1,1);
				p+=sum;
			}
		}
    }
    for(int i=0;i<26;i++) rev(rt[i],1,n,'a'+i);
    for(int i=1;i<=n;i++) cout<<s[i];
}
2024/11/20 10:57
加载中...