求调玄关
  • 板块学术版
  • 楼主xzz_cat6
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/1/20 21:17
  • 上次更新2025/1/21 09:05:47
查看原帖
求调玄关
773813
xzz_cat6楼主2025/1/20 21:17

题目

用的 AVL 树,分裂是双 log 的,其他操作均是单 log。目前 MLE+TLE+RE ,34分。求调或者复杂度证伪

#include<bits/stdc++.h>
#define N 200005
#define ll long long
using namespace std;
int q,rt[N];
ll lstans;
struct operate{
	#define BF(u) (h[ch[u][0]]-h[ch[u][1]])
	#define ls(u) (ch[u][0])
	#define rs(u) (ch[u][1])
	int tot,ch[N*90][2],siz[N*90],val[N*90],h[N*90],tag[N*90];
	ll sum[N*90];
	int newnode(int x){
		int u=++tot;
		val[u]=sum[u]=x,siz[u]=h[u]=1,ls(u)=rs(u)=tag[u]=0;
		return u;
	}
	int copy(int x){
		if(!x)	return 0;
		int u=++tot;
		val[u]=val[x],sum[u]=sum[x],siz[u]=siz[x];
		h[u]=h[x],ls(u)=ls(x),rs(u)=rs(x),tag[u]=tag[x];
		return u;
	}
	void pushup(int u){
		siz[u]=siz[ls(u)]+siz[rs(u)]+1;
		h[u]=max(h[ls(u)],h[rs(u)])+1;
		sum[u]=sum[ls(u)]+sum[rs(u)]+val[u];
	}
	void pushdown(int u){
		if(!tag[u])	return;
		swap(ls(u),rs(u));
		ls(u)=copy(ls(u));
		rs(u)=copy(rs(u));
		if(ls(u))	tag[ls(u)]^=tag[u];
		if(rs(u))	tag[rs(u)]^=tag[u];
		tag[u]=0;
	}
	void rotate(int &u,bool f){
		int v=copy(ch[u][f]);
		pushdown(v);
		ch[u][f]=ch[v][!f];
		ch[v][!f]=u;
		pushup(u),pushup(v),u=v;
	}
	void maintain(int &u){
		pushdown(u);
		int chk=BF(u);
		if(chk>1){
			pushdown(ls(u)=copy(ls(u)));
			if(BF(ls(u))<=0)	rotate(ls(u),1);
			rotate(u,0);
		}
		else if(chk<-1){
			pushdown(rs(u)=copy(rs(u)));
			if(BF(rs(u))>=0)	rotate(rs(u),0);
			rotate(u,1);
		}
		else if(u)	pushup(u);
	}
	int merge(int u,int v){
		if(!u||!v)	return u+v;
		int tmp=h[u]-h[v];
		if(abs(tmp)<=1){
			u=copy(u),v=copy(v);
			pushdown(u),pushdown(v);
			if(tmp>=0){
				int w=kth(u,siz[u]),nrt;
				del(u,siz[u]),nrt=newnode(w);
				ls(nrt)=u,rs(nrt)=v,maintain(nrt);
				return nrt;
			}
			else{
				int w=kth(v,1),nrt;
				del(v,1),nrt=newnode(w);
				ls(nrt)=u,rs(nrt)=v,maintain(nrt);
				return nrt;
			}
		}
		if(h[u]>h[v]){
			u=copy(u),pushdown(u);
			rs(u)=merge(rs(u),v);
			maintain(u);
			return u;
		}
		else{
			v=copy(v),pushdown(v);
			ls(v)=merge(u,ls(v));
			maintain(v);
			return v;
		}
	}
	void split(int &rt1,int &rt2,int u,int k){
		pushdown(u);
		int x=ls(u),y=rs(u),z=newnode(val[u]);
		if(x){
			if(siz[x]<=k)	rt1=merge(rt1,x);
			else	split(rt1,rt2,x,k);
		}
		if(1+siz[x]<=k)	rt1=merge(rt1,z);
		else	rt2=merge(rt2,z); 
		if(y){
			if(k<=siz[x]+1)	rt2=merge(rt2,y);
			else	split(rt1,rt2,y,k-siz[x]-1);
		}
	}
	void insert(int &u,int k,int w){
		if(!u)	return void(u=newnode(w));
		pushdown(u);
		if(k<=siz[ls(u)]){
			ls(u)=copy(ls(u));
			insert(ls(u),k,w);
		}
		else{
			rs(u)=copy(rs(u));
			insert(rs(u),k-siz[ls(u)]-1,w);
		}
		maintain(u);
	}
	void del(int &u,int k){
		pushdown(u);
		if(k==siz[ls(u)]+1){
			int v=u;
			if(ls(u)&&(v=rs(u))){
				while(ls(v))	v=ls(v);
				val[u]=val[v],rs(u)=copy(rs(u));
				del(rs(u),1);
			}
			else	u=ls(u)?ls(u):rs(u);
		}
		else if(k<=siz[ls(u)]){
			ls(u)=copy(ls(u));
			del(ls(u),k);
		}
		else{
			rs(u)=copy(rs(u));
			del(rs(u),k-siz[ls(u)]-1);
		}
		maintain(u);
	}
	int kth(int u,int x){
		int tmp=0;
		while(u){
			pushdown(u);
			if((tmp=siz[ls(u)]+1)==x)	return val[u];
			else	u=((tmp>x)?ls(u):(x-=tmp,rs(u)));
		}
		return -1;
	}
	void change(int &u,int l,int r){
		int x=0,y=0,z=0,t=0;
		if(r!=siz[u])	split(t,z,u,r);
		else	t=u;
		if(l!=1)	split(x,y,t,l-1);
		else	y=t;
		y=copy(y),tag[y]^=1;
		u=merge(merge(x,y),z);
	}
	ll query(int u,int k){
		pushdown(u);
		int res=0;
		if(k<siz[ls(u)])	return query(ls(u),k);
		if(k==siz[ls(u)])	return sum[ls(u)];
		if(k==siz[ls(u)]+1)	return sum[ls(u)]+val[u];
		if(k>siz[ls(u)]+1)	return query(rs(u),k-siz[ls(u)]-1)+sum[ls(u)]+val[u];
	}
	void print(int x){
		if(!x)	return;
		cout<<x<<' '<<val[x]<<' '<<val[ls(x)]<<' '<<val[rs(x)]<<' '<<siz[x]<<' '<<sum[x]<<' '<<tag[x]<<'\n';
		print(ls(x)),print(rs(x));
	}
}T;
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>q;
	for(int i=1;i<=q;i++){
		int op,id;
		ll y,x;
		cin>>id>>op,rt[i]=T.copy(rt[id]);
		switch(op){
			case 1:{
				cin>>x>>y;
				x^=lstans;
				y^=lstans;
				T.insert(rt[i],x,y);
				break;
			}
			case 2:{
				cin>>x,x^=lstans;
				T.del(rt[i],x);
				break;
			}
			case 3:{
				cin>>x>>y;
				x^=lstans;
				y^=lstans;
				T.change(rt[i],x,y);
				break;
			}
			case 4:{
				cin>>x>>y;
				x^=lstans;
				y^=lstans;
				cout<<(lstans=T.query(rt[i],y)-T.query(rt[i],x-1))<<'\n';
				break;
			}
		}
	}
	return 0;
}
2025/1/20 21:17
加载中...