2019.03.24【SPOJ-GSS8】Can you answer these queries VIII(treap)二项式展开

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/88784617

传送门


都是套路不想写题解了。


代码:

#include<bits/stdc++.h>
#define int unsigned int
#define re register
#define gc get_char
#define cs const

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<20|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	inline int getint(){
		re char c;
		while(!isdigit(c=gc()));re int num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline char getalpha(){
		re char c;
		while(!isalpha(c=gc()));return c;
	}
}
using namespace IO;

using std::cout;
using std::cerr;

struct mp{
	int first,second;
	mp(){}
	mp(cs int &_f,cs int &_s):first(_f),second(_s){}
};
typedef mp pii;

int c[11][11];
inline void init(){
	for(int re i=0;i<=10;++i){
		c[i][0]=c[i][i]=1;
		for(int re j=1;j<i;++j)
		c[i][j]=c[i-1][j-1]+c[i-1][j];
	}
}

cs int N=2e5+5;
int son[N][2],siz[N],val[N];
int ans[N][11];

inline int newnode(cs int &_val){
	static int tot;
	++tot;
	siz[tot]=1;
	val[tot]=_val;
	for(int re i=0;i<=10;++i)ans[tot][i]=_val;
	return tot;
}

inline void pushup(int u){
	int lc=son[u][0],rc=son[u][1];
	siz[u]=siz[lc]+siz[rc]+1;
	static int po[11];
	po[0]=1;
	for(int re i=1;i<=10;++i)po[i]=po[i-1]*(siz[lc]+1);
	for(int re i=0;i<=10;++i){
		ans[u][i]=ans[lc][i]+val[u]*po[i];
		for(int re j=0;j<=i;++j)
		ans[u][i]+=ans[rc][j]*po[i-j]*c[i][j];
	}
}

inline pii split(int now,cs int &key){
	if(!now)return mp(0,0);
	pii res;
	if(siz[son[now][0]]+1<=key){
		res=split(son[now][1],key-siz[son[now][0]]-1);
		son[now][1]=res.first;
		res.first=now;
	}
	else {
		res=split(son[now][0],key);
		son[now][0]=res.second;
		res.second=now;
	}
	pushup(now);
	return res;
}

inline int merge(int a,int b){
	if(!a||!b)return a|b;
	if((long long)siz[a]*rand()>(long long)siz[b]*rand()){
		son[a][1]=merge(son[a][1],b);
		pushup(a);
		return a;
	}
	else {
		son[b][0]=merge(a,son[b][0]);
		pushup(b);
		return b;
	}
}

int rt;

inline int build(int l,int r){
	if(l==r)return newnode(getint());
	int mid=(l+r)>>1;
	int lc=build(l,mid),rc=build(mid+1,r);
	return merge(lc,rc);
}

inline void Ins(int pos,int val){
	pii res=split(rt,pos-1);
	rt=merge(res.first,merge(newnode(val),res.second));
}

inline void Del(int pos){
	pii res1=split(rt,pos-1);
	pii res2=split(res1.second,1);
	rt=merge(res1.first,res2.second);
}

inline void Change(int pos,int _val){
	pii res1=split(rt,pos-1);
	pii res2=split(res1.second,1);
	rt=merge(res1.first,merge(newnode(_val),res2.second));
}

inline int Query(int l,int r,int k){
	pii res1=split(rt,r);
	pii res2=split(res1.first,l-1);
	int res=ans[res2.second][k];
	rt=merge(merge(res2.first,res2.second),res1.second);
	return res;
}

int n;
signed main(){
	init();
	srand(time(0));
	rt=build(1,getint());
	n=getint();
	while(n--)switch(getalpha()){
		case 'I':{
			int pos=getint()+1,val=getint();
			Ins(pos,val);
			break;
		}
		case 'D':Del(getint()+1);break;
		case 'R':{
			int pos=getint()+1,val=getint();
			Change(pos,val);
			break;
		}
		case 'Q':{
			int l=getint()+1,r=getint()+1,k=getint();
			cout<<Query(l,r,k)<<"\n";
			break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/88784617
今日推荐