解题思路
这道题真的卡了我几个小时。。一开始看思路就没看懂,然后看了标才理解的。。呜呜,我太菜了
(首先要理解,
t
r
e
e
[
k
]
.
x
tree[k].x
tree[k].x存的是最终这个区间中的字符)
我们维护每个区间
[
l
,
r
]
[l,r]
[l,r]的字符x是什么,一开始建树的时候,每个叶子结点都相应的代表一个字符。如果两个子区间的字符都一样,就把他的爸爸的字符状态改为他子区间的字符。然后对于每一次询问,统计询问的区间
[
l
l
.
r
r
]
[ll.rr]
[ll.rr]中每个字符出现的次数
l
e
n
len
len。
当升序排列时,按字典序枚举 26 26 26个字符,如果这个字符 i i i在 [ l l . r r ] [ll.rr] [ll.rr]中出现,就把 l l l l + l e n [ i ] ll~ll+len[i] ll ll+len[i]这段区间全部跟改为 i , l l + = l e n [ i ] i,ll+=len[i] i,ll+=len[i]
最后输出这个字符串的时候,如果区间有标记字母,就输出标记的字母,输出次数为区间长度。
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int n,m,w,l,r,len[27];
char s[100010];
struct c{
int l,r,x;
}tree[1000010];
void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r;
if(l==r)
{
tree[k].x=s[l]-'a'+1;
return;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
if(tree[k*2].x==tree[k*2+1].x)
tree[k].x=tree[k*2].x;
}
void up(int k,int x,int y){
if(tree[k].l>=x&&tree[k].r<=y&&tree[k].x!=0)
{
len[tree[k].x]+=tree[k].r-tree[k].l+1;
return;
}
if(tree[k].x)
{
tree[k*2].x=tree[k].x;
tree[k*2+1].x=tree[k].x;
}
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid)up(k*2,x,y);
if(y>mid)up(k*2+1,x,y);
}
void change(int k,int x,int y,int v)
{
if(tree[k].l>=x&&tree[k].r<=y)
{
tree[k].x=v;
return;
}
if(tree[k].x)
{
tree[k*2].x=tree[k].x;
tree[k*2+1].x=tree[k].x;
tree[k].x=0;
}
int mid=(tree[k].l+tree[k].r)/2;
if(x<=mid)change(k*2,x,y,v);
if(y>mid)change(k*2+1,x,y,v);
if(tree[k*2].x==tree[k*2+1].x)
tree[k].x=tree[k*2].x;
}
void print(int x)
{
if(tree[x].x)
{
int l=tree[x].r-tree[x].l+1;
for(int i=1;i<=l;i++)
putchar(tree[x].x+'a'-1);
return;
}
print(x*2);print(x*2+1);
}
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+1);
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&w);
memset(len,0,sizeof(len));
up(1,l,r);
int ll=l;
if(w==1)
{
for(int i=1;i<=26;i++)
{
if(len[i])
{
change(1,ll,ll+len[i]-1,i);
ll+=len[i];
}
}
}
if(w==0)
{
for(int i=26;i>0;i--)
{
if(len[i])
{
change(1,ll,ll+len[i]-1,i);
ll+=len[i];
}
}
}
}
print(1);
}