JZOJ P5829 HZOI 20190801 A string segment tree

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;
}

Guess you like

Origin www.cnblogs.com/Juve/p/11286506.html