TRIE树套TRIE树TLE70分求助
查看原帖
TRIE树套TRIE树TLE70分求助
147670
金珂拉楼主2021/5/29 14:15
#include<bits/stdc++.h>
#define N 2000010
using namespace std;
template<int lim>
struct kthtrie{
template<short lm>
struct Trie{
	int ch[4000005][2],d[4000005],v[4000005],sum[4000005],s[4000005],tot=1,rt[4000005];
	int New(int p,int dep){
		sum[++tot]=p;d[tot]=dep;return tot;
	}
	int g(int x,int i){return (x>>i)&1;}
    int rev(int x){
	int ans=0;
	for(int i=0;i<lm;++i)ans+=g(x,i)<<(lm-i-1);
	return ans;
    }
	void add(int x,int val,int t){int v1=x;x=rev(x);int p=(rt[t])? rt[t]:rt[t]=++tot,k=0,lt=0;
		for(int i=0;i<lm;++i){k++;int c1=g(x,i);
			while(i>d[p]){if(!ch[p][c1]){ch[p][c1]=New(x>>i,lm);
				v[tot]=v1;
				s[ch[p][c1]]=val;
				return;}
			lt=p;k=i-d[p];p=ch[p][c1];
			s[lt]+=val;}
			int c2=g(sum[p],k-1);
			if(c1!=c2){int u=New(sum[p],i-1);s[u]=s[p]+val;
				ch[u][c2]=p;ch[u][c1]=New(x>>i,lm);
				ch[lt][g(sum[p],0)]=u;
				sum[p]>>=(k-1);
				lt=u;p=ch[u][c1];k=1;s[p]+=val;v[p]=v1;
				return;}}
		s[p]+=val;}
	void insert(int x,int t){add(x,1,t);}
	void erase(int x,int t){add(x,-1,t);}
	int rank(int x,int t){add(x,0,t);
		x=rev(x);
		int p=(rt[t])? rt[t]:rt[t]=++tot,ans=0;	
		for(int i=0;i<lm;++i){int c1=g(x,i);
			while(i>d[p])
			{if(c1==1)ans+=s[ch[p][0]];
			p=ch[p][c1];}}
		return ans;}
	int kth(int x,int t){int p=(rt[t])? rt[t]:rt[t]=++tot,k=x;
		while(ch[p][0]||ch[p][1])if(k<=s[ch[p][0]]) p=ch[p][0];else k-=s[ch[p][0]],p=ch[p][1];
		return v[p];}	
	int pre(int x,int t){return kth(rank(x,t),t);}
	int nt(int x,int t){return kth(rank(x+1,t)+1,t);}
};
Trie<20> st;
long long lf[N],ch[2][N],tot,v[N],fa[N],val[N];
inline int New(){tot++;return tot;}
long long rev(long long x){
long long ans=0;
	for(int i=0;i<lim;++i) ans+=((x>>i)&1)<<(lim-i-1);
	return ans;
}
inline void insert(long long x,int t){
int temp=0;
v[t]=x;
x=rev(x);
int p=1;
for(int i=1;i<=lim;i++){
	if(!ch[x&1][p]){
		ch[x&1][p]=New();fa[ch[x&1][p]]=p;}
		p=ch[x&1][p];
		st.insert(t,p);
		x>>=1;
		}
lf[t]=p;
val[p]=v[t];
}
inline int getway(int p){
	return p==ch[1][fa[p]];
}
inline void del(int t){
	int p=lf[t];
	while(p!=1){
		st.erase(t,p);
		p=fa[p];
	}
}
inline void change(int t,int val){
	del(t);
	insert(val,t); 
}
inline int getsize(int p,int l,int r){
	return st.rank(r+1,p)-st.rank(l,p);
}
inline int getrank(int l,int r,int x){
x=rev(x);
int ans=0;
int p=1;
while(ch[1][p]  || ch[0][p]){
	if(x&1)
	{
	ans+=getsize(ch[0][p],l,r);
	}
	p=ch[x&1][p];
	x>>=1;
    }
    return ans+1;
}
int kth(int l,int r,int k){
	int p=1;
	while(ch[1][p]  || ch[0][p])
	{
	int temp=getsize(ch[0][p],l,r);
		if(temp<k){
			p=ch[1][p];k-=temp;
		}else p=ch[0][p];
	}
	return v[st.kth(1,p)];
}
};
kthtrie<28> tr;
int t=0;
int main(){
	tr.New();
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		tr.insert(x,i);
	    }
		for(int i=1;i<=m;i++){
		int l,r,k,op;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&l,&r,&k);
			printf("%d\n",tr.getrank(l,r,k));
		}
		if(op==2){
			scanf("%d%d%d",&l,&r,&k);
			printf("%d\n",tr.kth(l,r,k));
		}
		if(op==3){
			scanf("%d%d",&l,&k);
			tr.change(l,k);
		}
		if(op==4){
		scanf("%d%d%d",&l,&r,&k);
		int temp=tr.getrank(l,r,k);
		temp=(temp!=1) ? tr.kth(l,r,temp-1) : -2147483647;
		printf("%d\n",temp);
		}
		if(op==5){
		scanf("%d%d%d",&l,&r,&k);
		int temp=tr.getrank(l,r,k)-1;
		temp=(temp!=r-l+1) ? tr.kth(l,r,temp+1) : 2147483647;
		printf("%d\n",temp);
		}
	}
} 
2021/5/29 14:15
加载中...