26棵线段树=。=区间修改。如果L,R这段区间升序,那么从a依次放到z,降序,从z放到a.
怎么放呢?
假设放b
把l- r所有b取出。放到a后面。
注意优化
1.如果这段区间某字母的个数为0,就不用去放了
2.查找某区间某字母个数时,如果另一个区间,包含查询区间,但这一区间某字母个数为0,就不用递归了。
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],siz[27][450005],tag[27][450005],flag[27][450005];
inline void read(int &x)
{
x = 0;
int f = 0;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-') f = 1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = 10 * x + c - '0';
c = getchar();
}
if(f) x = -x;
}
void update(int o,int ha)
{
siz[ha][o] = siz[ha][o*2] + siz[ha][o*2 + 1] ;
}
void build(int o,int l,int r,int ha)
{
if(l == r)
{
if(a[l] == ha) siz[ha][o]++;
return;
}
int mid = (l + r) / 2;
build(o*2, l, mid, ha);
build(o*2+1, mid+1, r, ha);
update(o,ha);
}
void pushdown(int o,int ha,int l,int r)
{
if(flag[ha][o])
{
int mid = (l + r) / 2;
siz[ha][o * 2] = (mid - l + 1) * tag[ha][o];
siz[ha][o * 2 + 1] = (r - mid) * tag[ha][o];
flag[ha][o*2] = flag[ha][o*2+1] = 1;
flag[ha][o] = 0;
tag[ha] [o*2]= tag[ha][o*2+1] = tag[ha][o];
tag[ha][o] = 0;
}
}
void modify(int o,int l,int r,int ql,int qr,int val,int ha)
{
if(ql <= l && r <= qr)
{
siz[ha][o] = (r - l + 1) * val;
tag[ha][o] = val;
flag[ha][o] = 1;
return;
}
pushdown(o,ha,l,r);
int mid = (l + r) /2;
if(ql <= mid) modify(o*2, l, mid, ql, qr,val, ha);
if(qr > mid) modify(o*2+1, mid+1, r, ql, qr,val,ha);
update(o,ha);
}
int qurey(int o,int l,int r,int ql,int qr,int ha)
{
if(siz[ha][o] == 0) return 0;
if(ql <= l && r <= qr)
{
tag[ha][o] = 0;
flag[ha][o] = 1;
int he = siz[ha][o];
siz[ha][o] = 0;
return he;
}
pushdown(o,ha,l,r);
int rt = 0,mid = (l + r) /2;
if(ql <= mid) rt += qurey(o*2, l, mid, ql, qr, ha);
if(qr > mid) rt += qurey(o*2+1, mid+1, r, ql, qr,ha);
update(o,ha);
return rt;
}
int qurey1(int o,int l,int r,int pos,int ha)
{
if(siz[ha][o] == 0) return 0;
if(l == r)
{
return siz[ha][o];
}
pushdown(o,ha,l,r);
int mid = (l + r) / 2;
if(pos <= mid) return qurey1(o*2, l, mid, pos, ha);
else return qurey1(o*2+1,mid+1,r,pos,ha);
}
int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
read(n);
read(m);
for(register int i = 1; i <= n; i++)
{
char s;
scanf("%c",&s);
a[i] = s - 'a' + 1;
}
for(register int i = 1; i <= 26; i++)
{
build(1,1,n,i);
}
for(register int k = 1; k <= m; k++)
{
int l,r,x;
read(l); read(r); read(x);
int las = l;
if(x == 1)
for(register int i = 1; i <= 26; i++)
{
int he = qurey(1,1,n,l,r,i);
if(he > 0) modify(1,1,n,las,las + he - 1,1,i);
las = las + he;
}
else
for(register int i = 26; i >= 1; i--)
{
int he = qurey(1,1,n,l,r,i);
if(he > 0) modify(1,1,n,las,las + he - 1,1,i);
las = las + he;
}
}
for(register int k = 1; k <= n; k++)
{
for(register int i = 1; i <= 26; i++)
{
int he = qurey1(1,1,n,k,i);
if(he == 1){
printf("%c",i-1+'a');
break;
}
}
}
return 0;
}