bzoj 1455:ローマゲーム(並積み可能)

2977 ワード

1455:ローマゲーム


Time Limit: 5 Sec  
Memory Limit: 64 MB
Submit: 1346  
Solved: 557
[ Submit][ Status][ Discuss]

Description


ローマ皇帝は殺人ゲームが大好きです.彼の軍隊にはn人がいて、誰もが独立した団です.最近平面幾何学のテストが行われ、誰もが点数を取った.皇帝は平面幾何学が大好きで、得点の低い人に鼻をついて笑った.彼はこのようなゲームをすることにした.2つのコマンドを発行できます.1.Merger(i, j).iのいる団とjのいる団を一つの団にまとめる.i,jが死んだ人がいる場合は,その命令を無視する.2. Kill(i).iのいる団の中で最も得点の低い人を殺す.もしiという人が死んだら、この命令は無視します.皇帝は彼がkill命令を出すたびに、次の将軍が殺された人の点数を報告することを望んでいる.(このコマンドが無視された場合、0点を報告します)

Input


1行目の整数n(1<=n<=1000000).nは兵士数,mは総命令数を表す.2行目のn個の整数で、i番目の数はi番の兵士の点数を表す.3行目の整数m(1<=m<=10000000)3+i行目は、i番目のコマンドを記述する.コマンドは次の2つの形式です.1.M i j 2. K i

Output


命令がKillなら、対応するのは殺された点数を出力してください.(この人がいなければ0を出力)

Sample Input


5 100 90 66 99 10 7 M 1 5 K 1 K 1 M 2 3 M 3 4 K 5 K 4

Sample Output


10 100 0 66

HINT


Source


[ Submit][ Status][ Discuss]
标题解:左偏樹
左バイアスツリーの性質:基本構造は斜めスタックに似ています
1.【スタックの性質】:ノードのキーワードはその子ノードのキーワードに等しい
2.【左寄りの性質】:ノードから最も近いリーフノードまでの距離をノード距離と定義し、任意のノードの左の息子の距離が右の息子の距離より大きい
左偏樹は挿入操作を実現する際に常に右側から挿入し,すなわち常に短い側を成長させ,右側が左側より長ければ左右側を交換し,右側から成長を続ける
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1000003
using namespace std;
int n,m,a[N],fa[N];
int lch[N],rch[N],d[N],mark[N];
int find(int x)
{
	if (fa[x]==x) return x;
	fa[x]=find(fa[x]);
	return fa[x];
}
int merge(int x,int y)
{
	if (!x) return y;
	if (!y) return x;
	if (a[x]>a[y]) swap(x,y);
	rch[x]=merge(rch[x],y);
	if (d[lch[x]]<d[rch[x]])
	 swap(lch[x],rch[x]);
	d[x]=d[rch[x]]+1;
	return x;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]),fa[i]=i;
	scanf("%d",&m);
	for (int i=1;i<=m;i++)
	{
	   int x,y; char s[10];
	   scanf("%s",s);
	   if (s[0]=='M')
	    {
	    	scanf("%d%d",&x,&y);
	    	if (mark[x]||mark[y]) continue;
	    	int r1=find(x); int r2=find(y);
	    	if (r1!=r2)
	    	 {
	    	 	int t=merge(r1,r2);
	    	 	fa[r1]=fa[r2]=t;
	    	 }
	    }
	   else
	    {
	    	scanf("%d",&x);
	    	if (mark[x]) 
	    	{
	    		printf("0
"); continue; } int now=find(x); mark[now]=1; printf("%d
",a[now]); fa[now]=merge(lch[now],rch[now]); fa[fa[now]]=fa[now]; } } }