string segment tree

Problems encountered on the surface recall the sort of topic tree line, but finished mold sample found no correlation between ideas. Then think of splay in literary balanced tree, but that is the interval flip. Hastily knocked fast row and found themselves may merge Bibi speed code ( own sb, like, obviously is O (the n-* logN) ), then kx to shoot an entire field test, the speed is about the same. Correct answer is a barrel row + segment tree optimization. Consider barrel row, ordering the original topic of a problem in a lot of people have been drained by the barrel, but in fact the time is 6000ms, (hiahia) this question directly barrels a row sort of violence and division. Positive thinking process so consider Solutions, bucket sort discharge quickly but pretreatment, plus the sequence statistics are O (n). But consider very carefully you can find these two operations are processing section issues, a query, a modification. But the general said that was not enough, you will see what you do not clear the tree line store, think about the row bucket, bucket array is the source of ideas, but only 26 elements, then the answer is obvious, open 26 corresponding to the target segment tree under barrel . 1 is modified to cover, while the query is then covered to zero. Great idea!

#include<cstdio>
#include<iostream>
#define MAXN 100010
#define TR (MAXN<<2)
using namespace std;
inline int read(){
	int s=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
	return s;
}
#define kd (read())
int n,m;
int tong[27];
int sm[27][TR],lb[27][TR];
#define ls (u<<1)
#define rs (u<<1|1)
inline void up(int u,int id){
	sm[id][u]=sm[id][ls]+sm[id][rs];
}
inline void down(int u,int l,int r,int id){
	if(!lb[id][u])return ;
	int mid=l+r>>1;
	lb[id][ls]=lb[id][rs]=lb[id][u];
	if(lb[id][u]==-1)
		sm[id][rs]=sm[id][ls]=0;
	else{
		sm[id][ls]=mid-l+1;
		sm[id][rs]=r-mid;
	}
	lb[id][u]=0;
}
void upd(int u,int l,int r,int x,int y,int id){
	if(l>=x&&r<=y){
		sm[id][u]=(r-l+1);
		lb[id][u]=1;
		return ;
	}
	down(u,l,r,id);
	int mid=l+r>>1;
	if(x<=mid)upd(ls,l,mid,x,y,id);
	if(y>=mid+1)upd(rs,mid+1,r,x,y,id);
	up(u,id);
}
int query(int u,int l,int r,int x,int y,int id){
	if(!sm[id][u])return 0;
	if(l>=x&&r<=y){
		int res=sm[id][u];
		sm[id][u]=0;
		lb[id][u]=-1;
		return res;
	}
	down(u,l,r,id);
	int mid=l+r>>1;
	int res=0;
	if(x<=mid)res+=query(ls,l,mid,x,y,id);
	if(y>=mid+1)res+=query(rs,mid+1,r,x,y,id);
	up(u,id);
	return res;
}
void wks(int l,int r){
	for(int i=1;i<=26;++i)
		tong[i]=query(1,1,n,l,r,i);
	int p=l;
	for(int i=1;i<=26;++i)
		if(tong[i]){
			upd(1,1,n,p,p+tong[i]-1,i);
			p=p+tong[i];
		}
}
void wkj(int l,int r){
	for(int i=1;i<=26;++i)
		tong[i]=query(1,1,n,l,r,i);
	int p=l;
	for(int i=26;i>=1;--i)
		if(tong[i]){
			upd(1,1,n,p,p+tong[i]-1,i);
			p=p+tong[i];
		}
}
void pt(int u,int l,int r){
	if(l==r){
		for(int i=1;i<=26;++i)
			if(sm[i][u]){putchar(i+'a'-1);break;}
		return ;
	}
	for(int i=1;i<=26;++i)
		down(u,l,r,i);
	int mid=l+r>>1;
	pt(ls,l,mid);pt(rs,mid+1,r);
}
int main(){
//	freopen("da.in","r",stdin);
	n=kd;m=kd;
	char rn;
	for(int i=1;i<=n;++i){
		rn=getchar();
		upd(1,1,n,i,i,(rn-'a'+1));
	}
	int l,r,opt;
	for(int i=1;i<=m;++i){
		l=kd;r=kd;opt=kd;
		switch(opt){
			case 1:{wks(l,r);break;}
			case 0:{wkj(l,r);break;}
		}
	}
	pt(1,1,n);
	puts("");
}

 Segment tree bad habits, Down function is preferably determined in the following, this time to ensure the number of nodes MAXN × 4

Guess you like

Origin www.cnblogs.com/2018hzoicyf/p/11285521.html