社区讨论

我大力 Splay T了?

P4991愤怒的XiaoX参与者 4已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi7cu01n
此快照首次捕获于
2025/11/20 19:35
4 个月前
此快照最后确认于
2025/11/20 19:35
4 个月前
查看原帖
如题,附上帅气简洁的代码,复杂度不是 O(tqklogn)O(t*q*klogn) 吗 ,为什么过不去.
CPP
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void init(T&x){
	x=0;char ch=getchar();bool t=0;
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
	if(t) x=-x;
	return;
}
typedef long long ll;
int n;
const int N=5e4+1;
int bin[25];
#define ls son[0]
#define rs son[1]
#define __ NULL
#define get_son(a) (a->fa->rs==a)
#define get_size(a) ((a)? (a)->size:0)
struct node{
	node *son[2];node *fa;bool rev;int size;int x;
	void clear(){ls=rs=fa=__;rev=0;size=0;x=0;}
};
struct Splay{
	node pool[N];int cnt;node *rt;
	inline void update(node *p){p->size=get_size(p->ls)+get_size(p->rs)+1;return;}
	inline void Inv(node *p){if(!p) return;p->rev=!(p->rev);p->x^=1;return;}
	inline void push_down(node *p){if(!p) return;if(p->rev) Inv(p->ls),Inv(p->rs),p->rev=0;return;}
	inline void rotate(node *p){
		if(!p) return;int k=get_son(p);node* q=p->fa;
		if(q->rev) push_down(q);if(p->rev) push_down(p);
		q->son[k]=p->son[k^1];if(p->son[k^1]) p->son[k^1]->fa=q;
		p->fa=q->fa;if(q->fa) q->fa->son[get_son(q)]=p;
		q->fa=p;p->son[k^1]=q;return update(q);
	}
	inline void splay(node *p,node *goal){
		if(!p) return;if(!goal) rt=p;
		for(;p->fa!=goal;rotate(p)) if(p->fa->fa==goal) continue;else (get_son(p)==get_son(p->fa))? rotate(p->fa):rotate(p);
		return update(p);
	}
	inline void insert(int x){
		if(!rt) {rt=&pool[cnt++],rt->clear(),rt->x=x,rt->size=1;return;}
		node* p=rt;while(p->rs) p=p->rs;
		p->rs=&pool[cnt++];node* q=p->rs;
		q->clear();q->x=x;q->size=1;q->fa=p;splay(q,__);
		return;
	}
	inline node* Find(int k,bool Y){
		node *p=rt;
		while(k){
			int szl=get_size(p->ls);
			if(szl>=k) p=p->ls;
			else{k-=szl+1;if(!k) return Y? splay(p,__),p:p;p=p->rs;}
		}
		return Y? splay(p,__),p:p;
	}
	inline int Query(int p){return Find(p,1)->x;}
	inline node* get_interval(int l,int r){
		if(l==1&&r==n) return rt;
		node *L,*R;if(l==1) L=__;else L=Find(l-1,1);
		if(r==n) R=rt->rs;else R=Find(r+1,0),splay(R,L),R=R->ls;
		return R;
	}
	inline void invert(int l,int r) {return Inv(get_interval(l,r));}
}S[25];
ll ret[N];
int t,k;
inline void Swap(int p,int q,int l,int r){
	if(l==1&&r==n) return (void)(swap(S[p].rt,S[q].rt));
	node *L=S[p].get_interval(l,r),*R=S[q].get_interval(l,r);
	if(L->fa) swap(L->fa->son[get_son(L)],R->fa->son[get_son(R)]);
	swap(L->fa,R->fa);S[q].splay(L,__);S[p].splay(R,__);return;
}
int main()
{
	init(n);init(t);bin[0]=1;
	for(int k=1;k<25;++k) bin[k]=bin[k-1]<<1;
	for(int i=1;i<=n;++i) {ll x;init(x);ret[i]=x;for(int k=0;k<25;++k) S[k].insert((x>>k)&1),ret[i]-=(x&bin[k]);}
	for(int i=1;i<=t;++i){
		int K,q;init(q);init(K);--K;
		for(int j=1;j<=q;++j){
			int op,l,r,p;
			init(op);
			if(op==1) {init(l);init(r);for(int k=0;k<=K;++k) S[k].invert(l,r);}
			else if(op==2) {init(l);init(r);int p=0,q=K;while(p<q) Swap(p++,q--,l,r);}
			else {
				init(p);ll ans=0;
				for(int k=0;k<25;++k) if(S[k].Query(p)) ans|=bin[k];
				printf("%lld\n",ret[p]+ans);
			}
		}
	}
	return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...