Mn Zn 求调
  • 板块学术版
  • 楼主too_later
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/4/28 13:25
  • 上次更新2023/11/5 00:01:49
查看原帖
Mn Zn 求调
115857
too_later楼主2021/4/28 13:25

ORZ,已经调了很久很久了啊,求求诸位大神了。

https://darkbzoj.tk/problem/3217

#include<bits/stdc++.h>
#define I inline
#define RI register int
#define rep(i,a,b) for(RI i=a;i<=b;++i)
#define dow(i,a,b) for(RI i=a;i>=b;--i)
using namespace std;
const int N=2e5+5;
const double alpha=0.75;
int n,m;
char op[10];
class Trie_Tree{
public:
	int cnt,rt[N],ch[N<<6][2],sz[N<<6];
	I void init(int k){
		if(!k) return;
		if(ch[k][0]) init(ch[k][0]);
		if(ch[k][1]) init(ch[k][1]);
		sz[k]=ch[k][0]=ch[k][1]=0;
	}
	I void ins(int k,int x,int v){
		int now=rt[k];if(!now) rt[k]=now=++cnt;
		for(int i=21;~i;--i){
			if(!ch[now][(x>>i)&1])
				ch[now][(x>>i)&1]=++cnt;
			sz[now]+=v;now=ch[now][(x>>i)&1];
		}
		sz[now]+=v;
	}
} tr,tre;
class ScapSoapTree{
public:
#define ls ch[p][0]
#define rs ch[p][1]
	int top,tot,rt,ma1,mi1,ans,top1,top2,st2[N],st1[N],sz[N],sd[N],wn[N],val[N],ch[N][2],ma[N],mi[N],id[N];
	I void init(){ tot=n; }
	I void maintain(int p){
		sd[p]=sd[ls]+sd[rs]+!wn[p];sz[p]=sz[ls]+sz[rs]+1;
		int pre[5]={val[p],ma[ls],ma[rs],mi[ls],mi[rs]};if(wn[p]) pre[0]=0;
		sort(pre,pre+5,greater<int>());ma[p]=pre[0],mi[p]=pre[1];
	}
	I bool Can_Rbu(int p){ return 0;return !wn[p]&&((double)max(sz[ls],sz[rs])>=sz[p]*alpha)||((double)sd[p])<=sz[p]*(1.0-alpha); }
	I void Rbu_dfs(int p){ if(ls) Rbu_dfs(ls);if(!wn[p])id[++top]=p;if(rs) Rbu_dfs(rs); }
	I int Rbu_build(int l,int r){
		if(l>r) return 0;RI mid=l+r>>1,now=id[mid];tr.init(tr.rt[now]),tre.init(tr.rt[now]);
		rep(i,l,r) tr.ins(now,val[now],1);tre.ins(now,val[now],1),ch[now][0]=Rbu_build(l,mid-1),ch[now][1]=Rbu_build(mid+1,r);
		return maintain(now),now;
	}
	I int kth(int p,int k){
//		printf("kth %d %d %d %d %d\n",p,ls,sd[ls],val[p],k);
//		rep(i,1,100000000);
		if(sd[ls]>=k) return kth(ls,k);
		else{ k-=sd[ls]+!wn[p];if(k<=0) return val[p];return kth(rs,k);}
	}
	I void ins(int &p,int k,int v,int q){
//		printf("%d %d %d %d %d\n",val[p],p,k,v,q);
//		rep(i,1,100000000);
		if(q==1&&!p) return p=++tot,wn[p]=0,val[p]=v,tre.ins(p,v,q),tr.ins(p,v,q),maintain(p);
		if(q==-1&&val[p]==v&&!wn[p]) return wn[p]=1,tre.ins(p,v,q),tr.ins(p,v,q),maintain(p);
		tr.ins(p,v,q);if(sd[ls]+!wn[p]>=k) ins(ls,k,v,q); else ins(rs,k-sd[ls]-!wn[p],v,q);
		if(Can_Rbu(p)) top=0,Rbu_dfs(p),p=Rbu_build(1,top);return maintain(p);
	}
	I void change(int &p,int k,int from,int v){
		tr.ins(p,from,-1),tr.ins(p,v,1);if(sd[ls]>k) return change(ls,k,from,v),maintain(p);
		else{ k-=sd[ls]+!wn[p];if(k<=0) return val[p]=v,tre.ins(p,from,-1),tre.ins(p,v,1),maintain(p);return change(rs,k,from,v),maintain(p); }
	}
	I void querysd(int p,int l,int r,int ql,int qr){
//		printf("%d %d %d %d %d %d %d %d %d %d\n",p,sz[p],ls,sz[ls],rs,sz[rs],l,r,ql,qr);
		if(ql>qr) return;
		if(l>=ql&&r<=qr&&!wn[p]) { 
		if(ma[p]>ma1) mi1=ma1,ma1=ma[p];
		else if(ma[p]>mi1) mi1=ma[p];if(mi[p]>mi1) mi1=mi[p];
		st1[++top1]=p;return;}
		else if(!wn[p]&&ql<=l+sd[ls]&&l+sd[ls]<=qr){
		    if(val[p]>ma1&&ql<=l+sd[ls]&&l+sd[ls]<=qr) mi1=ma1,ma1=val[p];
	    	else if(val[p]>mi1&&ql<=l+sd[ls]&&l+sd[ls]<=qr) mi1=val[p];
		}
		if(ql<=l+sd[ls]&&l+sd[ls]<=qr&&!wn[p]) st2[++top2]=p;
		if(l+sd[ls]-1>=ql) querysd(ls,l,l+sd[ls]-1,ql,qr);
		if(l+sd[ls]+1<=qr) querysd(rs,l+sd[ls]+1,l+sd[p]-1,ql,qr);
	}
	I int query(int l,int r){
		top1=top2=0,ma1=0,mi1=0;
		querysd(rt,1,sd[rt],l,r);
		rep(i,1,top1) st1[i]=tr.rt[st1[i]];
		rep(i,1,top2) st2[i]=tre.rt[st2[i]];
		RI res=0;//printf("mi %d %d\n",ma1,mi1);
		dow(i,21,0){
		    RI now=0;
		    rep(j,1,top1) if(tr.sz[tr.ch[st1[j]][((mi1>>i)&1)^1]]) now=1;
		    rep(j,1,top2) if(tre.sz[tre.ch[st2[j]][((mi1>>i)&1)^1]]) now=1;
//		    printf("now %d %d\n",((mi1>>i)&1)^1,now);
//		    rep(j,1,top1) printf("%d ",tr.sz[st1[j]]);printf("T %d\n",mi1);
//		    rep(j,1,top2) printf("%d ",tre.sz[st2[j]]);printf("T %d\n",mi1);
		    if(now){
		        rep(j,1,top1) st1[j]=tr.ch[st1[j]][((mi1>>i)&1)^1];
		        rep(j,1,top2) st2[j]=tre.ch[st2[j]][((mi1>>i)&1)^1];
		        res+=(1<<i);
		    } else {
		        rep(j,1,top1) st1[j]=tr.ch[st1[j]][(mi1>>i)&1];
		        rep(j,1,top2) st2[j]=tre.ch[st2[j]][(mi1>>i)&1];
		    }
		}
		return res;
	}
	I void dfs(int p){ if(ls) dfs(ls);printf("%d %d %d %d %d\n",sd[p],ls,rs,wn[p],val[p]);if(rs) dfs(rs); }
#undef ls
#undef rs
} tree;
int main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n) scanf("%d",&tree.val[i]),tree.id[i]=i,tree.val[i]=tree.val[i];tree.init();
	tree.rt=tree.Rbu_build(1,n);
	int x,y,z,last,n0=n;
	rep(i,1,m){
		scanf("%s",op+1);
		if(op[1]=='I') scanf("%d%d",&x,&y),x=(x+last)%n0+1,y=(y+last)%1048576,n0++,tree.ins(tree.rt,x,y,1);
		if(op[1]=='D') scanf("%d",&x),x=(x+last)%n0+1,n0--,tree.ins(tree.rt,x,tree.kth(tree.rt,x),-1);
		if(op[1]=='C') scanf("%d%d",&x,&y),x=(x+last)%n0+1,y=(y+last)%1048576,tree.change(tree.rt,x,tree.kth(tree.rt,x),y);
		if(op[1]=='F') scanf("%d%d",&x,&y),x=(x+last)%n0+1,y=(y+last)%n0+1,printf("%d\n",last=tree.query(x,y));
//		tree.dfs(tree.rt);
	}
	return 0;
}

2021/4/28 13:25
加载中...