[可并堆] BZOJ 2333 [SCOI2011]棘手的操作

诶,脑子不好使了

一道裸题调了一晚上...


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;

inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
	return *p1++;
}

inline void read(int &x){
	char c=nc(),b=1;
	for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
	for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline void read(char *s){
	char c=nc(); int len=0;
	for (;c!='F' && c!='A';c=nc()) if (c=='U') { s[++len]=c,s[++len]=0; return; }
	s[++len]=c; s[++len]=nc(); s[++len]=0;
}

struct Heap{
	priority_queue<int> Q,del;
	bool empty(){
		return Q.size()==del.size();
	}
	int top(){
		while (!Q.empty() && !del.empty() && Q.top()==del.top()) Q.pop(),del.pop();
		return Q.top();
	}
	void pop(){
		while (!Q.empty() && !del.empty() && Q.top()==del.top()) Q.pop(),del.pop();
		Q.pop();
	}
	void push(int x){
		Q.push(x);
	}
	void erase(int x){
		del.push(x);
	}
}All;

const int N=300005;

inline int ran() { static int x=31253125; x+=(x<<4)+1; return x&65536; }
struct node{ 
	node *p,*l,*r; int key; 
	int f;
	void modify(int x){ key+=x; f+=x; } 
	void pushdown() { if (l) l->modify(f); if (r) r->modify(f); f=0; }
}nodes[N];
node *M(node *p,node *q){
	if (!p||!q) return (p?p:q);
	if (p->key<q->key) return M(q,p);
	p->pushdown();
	ran()?p->r=M(p->r,q):p->l=M(p->l,q);
	if (p->r) p->r->p=p; if (p->l) p->l->p=p;
	return p;
}

int n;
int all_add;
node *root[N];
int fat[N];

inline int Fat(int u){ return u==fat[u]?u:fat[u]=Fat(fat[u]); }

inline int Val(int x){
	node *pnt=nodes+x;
	int y=pnt->key;
	while (pnt->p) pnt=pnt->p,y+=pnt->f;
	return y;
}

int main()
{
	char order[10]; int Q,x,y,fx,fy;
	freopen("t.in","r",stdin);
	freopen("t.out","w",stdout);
	read(n);
	for (int i=1;i<=n;i++)
		read(nodes[i].key),nodes[i].l=nodes[i].r=nodes[i].p=NULL,root[i]=nodes+i,fat[i]=i,All.push(nodes[i].key);
	read(Q);
	while (Q--)
	{
		read(order);
		if (!strcmp(order+1,"U"))
		{
			read(x); read(y);
			fx=Fat(x); fy=Fat(y);
			if (fx!=fy){
				All.erase(root[fx]->key);
				All.erase(root[fy]->key);
				root[fx]=M(root[fx],root[fy]);
				fat[fy]=fx;
				All.push(root[fx]->key);
			}
		}
		else if (!strcmp(order+1,"A1"))
		{
			read(x); read(y); fx=Fat(x); 
			All.erase(root[fx]->key);
			node *p=nodes+x;
			p->pushdown(); 
			if (p->l) p->l->p=NULL; 
			if (p->r) p->r->p=NULL;
			node *itmp=M(p->l,p->r),*fa=p->p;
			p->key=Val(x); p->key+=y; p->p=p->l=p->r=NULL;
			if (fa)
			{
				if (fa->l==p) fa->l=itmp; else fa->r=itmp; if (itmp) itmp->p=fa;
			}
			else
			{
				root[fx]=itmp;
			}
			root[fx]=M(root[fx],p);
			All.push(root[fx]->key);
		}
		else if (!strcmp(order+1,"A2"))
		{
			read(x); read(y); 
			fx=Fat(x);
			All.erase(root[fx]->key);
			root[fx]->modify(y);
			All.push(root[fx]->key);
		}
		else if (!strcmp(order+1,"A3"))
		{
			read(x); all_add+=x;
		}
		else if (!strcmp(order+1,"F1"))
		{
			read(x); 
			printf("%d\n",Val(x)+all_add);
		}
		else if (!strcmp(order+1,"F2"))
		{
			read(x); fx=Fat(x);
			printf("%d\n",root[fx]->key+all_add);
		}
		else if (!strcmp(order+1,"F3"))
		{
			printf("%d\n",All.top()+all_add);
		}
	}
	return 0;
}


你可能感兴趣的:([可并堆] BZOJ 2333 [SCOI2011]棘手的操作)