萌新求助
查看原帖
萌新求助
358739
BFSDFS123楼主2021/10/20 14:13

已经卡了8个月了(?

darbzoj上已经过了,还没开O2.

求神仙调代码

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
template<class T>
inline void read(T &x)
{
	char ch;
	int f=1;
	while(((ch=getchar())<'0' || ch>'9') && ch!='-');
	
	if(ch=='-')
	{
		f=-1;
	}else{
		x=ch-'0';
	}
	while((ch=getchar())>='0' && ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
	}
	x*=f;
}
int OutN;
char Out[20];
template<class T>
inline void write(T x)
{
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	if(x)
	{
		OutN=0;
		while(x)
		{
			Out[OutN++]=x%10+'0';
			x/=10;
		}
		while(OutN--)
		{
			putchar(Out[OutN]);
		}
	}else{
		putchar('0');
	}
}
const int Maxn=70011;
const int V=70011;
const int Logn=20;
const int SZ=20000011;
const double ALPHA=0.75;
const double LOGALPHA=log(4.0)-log(3.0);
int n,v[Maxn];
namespace SegmentTree
{
	int lc[SZ],rc[SZ],sum[SZ];
	int Stack[SZ],Stop;
	inline void init(int x)
	{
		lc[x]=rc[x]=sum[x]=0;
	}
	inline int newNode()
	{
		int ret=Stack[Stop--];
		init(ret);
		return ret;
	}
	inline void insert(int &x,int l,int r,int pos,int v)
	{
		if(x==0)
		{
			x=newNode();
		}
		sum[x]+=v;
		if(l==r)
		{
			return ;
		}
		int mid=(l+r)>>1;
		if(pos<=mid)
		{
			insert(lc[x],l,mid,pos,v);
		}else{
			insert(rc[x],mid+1,r,pos,v);
		}
	}
	inline void newTree(int &x,int pos)
	{
		x=newNode();
		sum[x]++;
		int l=0,r=V,cur=x;
		while(l<r)
		{
			int mid=(l+r)>>1;
			if(pos<=mid)
			{
				cur=lc[cur]=newNode();
				r=mid;
			}else{
				cur=rc[cur]=newNode();
				l=mid+1;
			}
			sum[cur]++;
		}
	}
	inline void merge(int &x,int y)
	{
		if(y==0)
		{
			return ;
		}
		if(x==0)
		{
			x=newNode();
		}
		sum[x]+=sum[y]; 
		merge(lc[x],lc[y]);
		merge(rc[x],rc[y]);
	}
	inline void clear(int &x)
	{
		Stack[++Stop]=x;
		if(lc[x])
		{
			clear(lc[x]);
		}
		if(rc[x])
		{
			clear(rc[x]);
		}
		init(x);
		x=0;
	}
}
namespace ScapgoatTree
{
	int root;
	int lc[Maxn],rc[Maxn],sz[Maxn],rt[Maxn];
	int dfn[Maxn],dfnN,val[Maxn],valN;
	int maxDepth;
	inline int build(int l,int r)
	{
		int mid=(l+r)>>1,x=dfn[mid];
		SegmentTree::newTree(rt[x],v[x]);
		if(l<mid)
		{
			lc[x]=build(l,mid-1);
		}
		if(mid<r)
		{
			rc[x]=build(mid+1,r);
		}
		sz[x]=sz[lc[x]]+sz[rc[x]]+1;
		SegmentTree::merge(rt[x],rt[lc[x]]);
		SegmentTree::merge(rt[x],rt[rc[x]]);
		return x; 
	}
	inline void get(int x)
	{
		if(lc[x])
		{
			get(lc[x]);
		}
		dfn[++dfnN]=x;
		if(rc[x])
		{
			get(rc[x]);
		}
	}
	inline int rebuild(int x)
	{
		dfnN=0;
		get(x);
		for(register int i=1;i<=dfnN;i++)
		{
			SegmentTree::clear(rt[dfn[i]]);
			lc[dfn[i]]=rc[dfn[i]]=sz[dfn[i]]=0;
		}
		return build(1,dfnN);
	}
	inline void get(int x,int l,int r,int ql,int qr)
	{
		if(ql<=l && r<=qr)
		{
			dfn[++dfnN]=rt[x];
			return ;
		}
		int mid=l+sz[lc[x]];
		if(ql<mid && lc[x])
		{
			get(lc[x],l,mid-1,ql,qr);
		}
		if(ql<=mid && mid<=qr)
		{
			val[++valN]=v[x];
		}
		if(qr>mid && rc[x])
		{
			get(rc[x],mid+1,r,ql,qr);
		}
	}
	inline int query(int l,int r,int k)
	{
		valN=dfnN=0;
		get(root,1,n,l,r);
		l=0,r=V;
		while(l<r)
		{
			int ls=0,mid=(l+r)>>1;
			for(register int i=1;i<=dfnN;i++)
			{
				ls+=SegmentTree::sum[SegmentTree::lc[dfn[i]]];
			}
			for(register int i=1;i<=valN;i++)
			{
				if(l<=val[i] && val[i]<=mid)
				{
					ls++;
				}
			}
			if(ls>=k)
			{
				r=mid;
				for(register int i=1;i<=dfnN;i++)
				{
					dfn[i]=SegmentTree::lc[dfn[i]];
				}
			}else{
				k-=ls,l=mid+1;
				for(register int i=1;i<=dfnN;i++)
				{
					dfn[i]=SegmentTree::rc[dfn[i]];
				}
			}
		}
		return l;
	}
	inline void get(int x,int pos)
	{
		dfn[++dfnN]=x;
		if(sz[lc[x]]>=pos)
		{
			get(lc[x],pos);
		}else if(sz[lc[x]]+1==pos){
			return ;
		}else{
			get(rc[x],pos-sz[lc[x]]-1);
		}
	}
	inline void modify(int x,int value)
	{
		dfnN=0;
		get(root,x); 
		for(register int i=1;i<=dfnN;i++)
		{
			SegmentTree::insert(rt[dfn[i]],0,V,v[dfn[dfnN]],-1);
			SegmentTree::insert(rt[dfn[i]],0,V,value,1);
		}
		v[dfn[dfnN]]=value;
	}
	inline bool insert(int &x,int pos,int p,int d)
	{
		if(x==0)
		{
			sz[x=p]++;
			SegmentTree::newTree(rt[x],v[x]);
			return d<=maxDepth;
		}
		sz[x]++;
		SegmentTree::insert(rt[x],0,V,v[p],1);
		bool ret;
		if(pos<=sz[lc[x]]+1)
		{
			ret=insert(lc[x],pos,p,d+1);
		}else{
			ret=insert(rc[x],pos-sz[lc[x]]-1,p,d+1);
		}
		int lim=(int)(sz[x]*ALPHA);
		if(ret && (sz[lc[x]]>lim || sz[rc[x]]>lim))
		{
			x=rebuild(x);
			return false;
		}else{
			return ret;
		}
	}
	inline void insert(int pos,int p)
	{
		maxDepth=log(1.0*n)/LOGALPHA;
		insert(root,pos,p,0);
	}
}
int main()
{
	read(n);
	for(register int i=1;i<=n;i++)
	{
		read(v[i]);
		ScapgoatTree::dfn[i]=i;
	}
	for(register int i=1;i<SZ;i++)
	{
		SegmentTree::Stack[++SegmentTree::Stop]=SZ-i;
	}
	ScapgoatTree::root=ScapgoatTree::build(1,n);
	//
	int qN;
	read(qN); 
	int lastAns=0;
	while(qN--)
	{
		int x,y,z;
		char str[4]="\0";
		scanf("%s",str);
		switch(str[0])
		{
			case 'Q':{
				read(x);
				read(y);
				read(z);
				x^=lastAns;
				y^=lastAns;
				z^=lastAns;
				write(lastAns=ScapgoatTree::query(x,y,z));
				putchar('\n');
				break;
			}
			case 'M':{
				read(x);
				read(y);
				x^=lastAns;
				y^=lastAns;
				ScapgoatTree::modify(x,y);
				break;
			}
			default:{
				read(x);
				read(y);
				x^=lastAns;
				y^=lastAns;
				v[++n]=y;
				ScapgoatTree::insert(x,n);
				break;
			}
		}
	}
	return 0;
}
2021/10/20 14:13
加载中...