fhp做法求hack
查看原帖
fhp做法求hack
497817
羊摆摇楼主2025/8/5 16:49

T了,时间复杂度应该是对的,分析不出哪里假了,也没看出哪里卡循环了,sub#4全A,猜是op3的部分有问题,希望大佬支招

#include <bits/stdc++.h>
using namespace std;

#define LL long long
#define pb push_back
#define fr first
#define sc second
typedef const int Int;
typedef pair<int,int> pii;

Int N=2e5+5;

int n,op,x;

struct node{
	int l,r;
	int val;
	int rnk;
	int idx;
};

node tr[N];
int tot,root;

void split(int &x,int &y,Int v,Int p){
	if(!p){
		x=y=0;
		return;
	}
	if(tr[p].idx<=v){
		x=p;
		split(tr[p].r,y,v,tr[p].r);
	}
	else{
		y=p;
		split(x,tr[p].l,v,tr[p].l);
	}
}

int merge(Int x,Int y){
//	cout<<"x y: "<<x<<" "<<y<<endl;
	if(!x||!y)return x+y;
	if(tr[x].rnk<=tr[y].rnk){
		tr[x].r=merge(tr[x].r,y);
		return x;
	}
	else{
		tr[y].l=merge(x,tr[y].l);
		return y;
	}
}

int addp(Int &v,Int &num=1){
	tr[++tot]=node{0,0,num,rand(),v};
	return tot;
}

void insert(Int &v){
	int x,y;
	split(x,y,v,root);
	root=merge(merge(x,addp(v)),y);
}

int fix(Int &v,Int &x){
	int p=root;
	while(tr[p].idx^v)p=tr[p].idx>v?tr[p].l:tr[p].r;
	return tr[p].val+=x;
}

pair<pii,int> delt(Int &v){
	int x,y;
	split(x,y,v-1,root);
	int l=x,r=y;
	while(tr[l].r)l=tr[l].r;
	while(tr[r].l)r=tr[r].l;
	pii a=make_pair(tr[l].val,tr[r].val);
	split(r,y,tr[r].idx,y);
	tr[l].val+=tr[r].val-1;
	pair<pii,int> ret=make_pair(a,tr[l].val);
	root=merge(x,y);
	return ret;
}

pair<pii,int> res(Int &v,Int &num){
	int x,y;
	split(x,y,v,root);
	int l=x;
	while(tr[l].r)l=tr[l].r;
	pair<pii,int> ret=make_pair(pii{tr[l].val-num+1,num},tr[l].val);
	tr[l].val-=num-1;
//	cout<<x<<" "<<l<<" "<<k<<" "<<y<<endl;
	root=merge(x,merge(addp(v,num),y));
	return ret;
}

void debug(Int &p=root){
	if(!p)return;
	debug(tr[p].l);
	cout<<tr[p].idx<<" ";
	debug(tr[p].r);
}

struct opt{
	int op,p,num,cnt,opx;
};

opt rcd[N];
int h;

LL ans=1;

inline const LL A(Int &num){
	return 1LL*num*(num+1)/2;
}

int at=1;

void findat(){
	int p=root;
	while(tr[p].r)p=tr[p].r;
	at=tr[p].idx;
}

int main(){
//	freopen("a.out","r",stdin);
	srand((unsigned LL)time(NULL));
	scanf("%d",&n);
	insert(1);
	for(int i=1;i<=n;i++){
		scanf("%d",&op);
		if(op==1){
			ans+=fix(at,1);
			rcd[i]=opt{1,at,0,0,0};
		}
		else if(op==2){
			ans++;
			insert(i);
			findat();
			rcd[i]=opt{2,at,0,0,0};
		}
		else{
			scanf("%d",&x);
			if(rcd[x].op==1){
				ans-=fix(rcd[x].p,-1)+1;
				rcd[i]=opt{3,rcd[x].p,0,1,1};
			}
			else if(rcd[x].op==2){
				pair<pii,int> ret=delt(rcd[x].p);
				findat();
				ans-=A(ret.fr.fr)+A(ret.fr.sc);
				ans+=A(ret.sc);
				rcd[i]=opt{3,rcd[x].p,ret.fr.sc,1,2};
			}
			else{
				if(rcd[x].opx==1){
					if(rcd[x].cnt&1)ans+=fix(rcd[x].p,1);
					else ans-=fix(rcd[x].p,-1)+1;
				}
				else if(rcd[x].opx==2){
					if(rcd[x].cnt&1){
						pair<pii,int> ret=res(rcd[x].p,rcd[x].num);
						findat();
						ans+=A(ret.fr.fr)+A(ret.fr.sc);
						ans-=A(ret.sc);
					}
					else {
						pair<pii,int> ret=delt(rcd[x].p);
						findat();
						ans-=A(ret.fr.fr)+A(ret.fr.sc);
						ans+=A(ret.sc);
					}
				}
				rcd[i]=opt{3,rcd[x].p,rcd[x].num,rcd[x].cnt+1,rcd[x].opx};
			}
		}
		printf("%lld\n",ans);
//		cout<<"debug:";
//		debug();
//		cout<<endl;
	}
	return 0;
}

//1 2 3
//100 100 100
//100 200 100
//300 200 100

/*
18
1
3 1
3 2
1 
1
1
2 
1 
1
1
3 7
3 11
3 12
2
2
1
1
3 13

*/


















2025/8/5 16:49
加载中...