Questions surface: https://www.cnblogs.com/Juve/articles/11286476.html
This question reminds ordering the examination room: https://www.cnblogs.com/Juve/p/11269638.html
n times half?
Pro-test TLE, 0 minutes
You sort of violence has 40 points
Of course this is not such a problem
We learn from the sort of thinking
We use the tree line to complete the operation, so what we want to save the tree line, what is labeled lazy
Just learn from that question, we will mark into one node information and lazy
Set tr [k] .val, if the interval k jurisdiction where the letters are the same letter, the tr [k] .val is that letter, otherwise tr [k] .val = 0,
This is very easy to maintain:
down:
if(!tr[k].val) return ; tr[k<<1].val=tr[k<<1|1].val=tr[k].val;
up:
if(tr[k<<1].val==tr[k<<1|1].val) tr[k].val=tr[k<<1].val;
For every time we first sort [L, R], the query [L, R], the number of occurrences of the letter 26 cnt [i],
achieve:
if(opl<=l&&r<=opr&&tr[k].val){ cnt[tr[k].val]+=(r-l+1); return ; }
If the ascending order, put the [L, R] in front cnt [a] modified a, followed cnt [b] modified b ,. . . . . .
Descending to turn
Finally, the output is over tree line dfs, then. . . In fact, nothing of the
To the code:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define MAXN 100005 #define re register using namespace std; int n,m,a[MAXN],cnt[28]; char ch[MAXN] struct Segtree{ int l,r,val; }tr[MAXN<<2]; void down(int k,int data){ if(!tr[k].val) return ; tr[k<<1].val=tr[k<<1|1].val=tr[k].val; tr[k].val=data; } void build(int k,int l,int r){ tr[k].l=l,tr[k].r=r; if(l==r){ tr[k].val=a[l]; return ; } int mid=(l+r)>>1; build(k<<1,l,mid),build(k<<1|1,mid+1,r); if(tr[k<<1].val==tr[k<<1|1].h) tr[k].val=tr[k<<1].val; } void get_cnt(int k,int opl,int opr){ int l=tr[k].l,r=tr[k].r; if(opl<=l&&r<=opr&&tr[k].val){ cnt[tr[k].val]+=(r-l+1); return ; } down(k,tr[k].val); int mid=(l+r)>>1; if(opl<=mid) get_cnt(k<<1,opl,opr); if(opr>mid) get_cnt(k<<1|1,opl,opr); } void change(int k,int opl,int opr,int data){ if(tr[k].val==data) return ; int l=tr[k].l,r=tr[k].r; if(opl<=l&&r<=opr){ tr[k].val=data; return ; } down(k,0); int mid=(l+r)>>1; if(opl<=mid) change(k<<1,opl,opr,data); if(opr>mid) change(k<<1|1,opl,opr,data); if(tr[k<<1].val==tr[k<<1|1].val) tr[k].val=tr[k<<1].val; } void print(int k){ if(tr[k].val){ int l=tr[k].l,r=tr[k].r; for(int i=l;i<=r;i++) putchar(tr[k].val-1+'a'); return ; } print(k<<1),print(k<<1|1); } int main(){ scanf("%d%d",&n,&m); scanf("%s",ch+1); for(re int i=1;i<=n;i++) a[i]=ch[i]-'a'+1; build(1,1,n); for(re int i=1,x,l,r;i<=m;i++){ scanf("%d%d%d",&l,&r,&x); memset(cnt,0,sizeof(cnt)); get_cnt(1,l,r); if(x==0){ for(re int j=26;j> = 1; j -) { exchange (1, l, l + cnt [j] -1, j); l+=cnt[j]; } }else{ for(re int j=1;j<=26;j++){ change(1,l,l+cnt[j]-1,j); l+=cnt[j]; } } } print(1); puts(""); return 0; }