BZOJ1180 OTOCI(LCT動態樹)

Some time ago Mirko founded a new tourist agency named "Dreams of Ice". The agency purchased N icy islands near the South Pole and now offers excursions. Especially popular are the emperor penguins, which can be found in large numbers on the islands.

Mirko's agency has become a huge hit; so big that it is no longer cost-effective to use boats for the excursions. The agency will build bridges between islands and transport tourists by buses. Mirko wants to introduce a computer program to manage the bridge building process so that fewer mistakes are made.

The islands are numbered 1 through N. No two islands are initially connected by bridges. The initial number of penguins on each island is known. That number may change, but will always be between 0 and 1000 (inclusive).

Your program must handle the following three types of commands:

  • "bridge A B" – an offer was received to build a bridge between islands A and B (A and B will be different). To limit costs, your program must accept the offer only if there isn't already a way to get from one island to the other using previously built bridges. If the offer is accepted, the program should output "yes", after which the bridge is built. If the offer is rejected, the program should output "no".
  • "penguins A X" – the penguins on island A have been recounted and there are now X of them. This is an informative command and your program does not need to respond.
  • "excursion A B" – a group of tourists wants an excursion from island A to island B. If the excursion is possible (it is possible to get from island A to B), the program should output the total number of penguins the tourists would see on the excursion (including islands A and B). Otherwise, your program should output "impossible".

Input

The first line contains the integer N (1 ≤ N ≤ 30 000), the number of islands.

The second line contains N integers between 0 and 1000, the initial number of penguins on each of the islands.

The third line contains an integer Q (1 ≤ Q ≤ 300 000), the number of commands.

Q commands follow, each on its own line.

Output

Output the responses to commands "bridge" and "excursion", each on its own line.

Example

Input:
5
4 2 4 5 6
10
excursion 1 1
excursion 1 2
bridge 1 2
excursion 1 2
bridge 3 4
bridge 3 5
excursion 4 5
bridge 1 3
excursion 2 4
excursion 2 5

Output:
4
impossible
yes
6
yes
yes
15
yes
15
16


Input:
6
1 2 3 4 5 6
10
bridge 1 2
bridge 2 3
bridge 4 5
excursion 1 3
excursion 1 5
bridge 3 4
excursion 1 5
penguins 3 10
excursion 1 3
bridge 1 5

Output:
yes
yes
yes
6
impossible
yes
15
13
no

中文題意:


Description
給出n個結點以及每個點初始時對應的權值wi。起始時點與點之間沒有連邊。有3類操作: 1、bridge A B:詢問結點A與結點B是否連通。如果是則輸出“no”。否則輸出“yes”,並且在結點A和結點B之間連一條無向邊。 2、penguins A X:將結點A對應的權值wA修改爲X。 3、excursion A B:如果結點A和結點B不連通,則輸出“impossible”。否則輸出結點A到結點B的路徑上的點對應的權值的和。給出q個操作,要求在線處理所有操作。數據範圍:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

Input
第一行包含一個整數n(1<=n<=30000),表示節點的數目。第二行包含n個整數,第i個整數表示第i個節點初始時對應的權值。第三行包含一個整數q(1<=n<=300000),表示操作的數目。以下q行,每行包含一個操作,操作的類別見題目描述。任意時刻每個節點對應的權值都是1到1000的整數。

Output
輸出所有bridge操作和excursion操作對應的輸出,每個一行。

Sample Input
5
4 2 4 5 6
10
excursion 1 1
excursion 1 2
bridge 1 2
excursion 1 2
bridge 3 4
bridge 3 5
excursion 4 5
bridge 1 3
excursion 2 4
excursion 2 5

Sample Output
4
impossible
yes
6
yes
yes
15
yes
15
16

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(x) tree[x].fa
#define LC(x) tree[x].child[0]
#define RC(x) tree[x].child[1]
#define REV(x) tree[x].rev
#define Size 300010
using namespace std;
inline int read(){
	int sum=0,fg=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')fg=-1;c=getchar();}
	while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
	return sum*fg;
}
struct lct{
	int fa,child[2],rev,add;
	int v,sum;
}tree[Size];
struct link_cut_tree{
	inline bool isroot(int x){
		return LC(F(x))!=x && RC(F(x))!=x;
	}
	inline void pushup(int x){
		tree[x].sum=tree[LC(x)].sum+tree[RC(x)].sum+tree[x].v;
	}
	inline void pushdown(int x){
		if(REV(x)){
			REV(x)^=1;REV(LC(x))^=1;REV(RC(x))^=1;
			swap(LC(x),RC(x));
		}
	}
	void Pushdown(int x){
		if(!isroot(x))Pushdown(F(x));
		pushdown(x);
	}
	inline void rotate(int x){
		int A=F(x),B=F(A);bool w=(RC(A)==x);
		if(!isroot(A)){
			if(LC(B)==A)LC(B)=x;
			else if(RC(B)==A)RC(B)=x;
		}
		F(tree[x].child[w^1])=A;F(A)=x;F(x)=B;
		tree[A].child[w]=tree[x].child[w^1];tree[x].child[w^1]=A;
		pushup(A);pushup(x);
	}
	inline void splay(int x){
		Pushdown(x);
		while(!isroot(x)){
			if(!isroot(F(x)))rotate(x);
			rotate(x);
		}
	}
	inline void access(int x){
		for(int i=0;x;i=x,x=F(x))splay(x),RC(x)=i,pushup(x);
	}
	inline int find_root(int x){
		access(x);splay(x);
		while(LC(x))x=LC(x);
		return x;
	}
	inline void reverse(int x){
		access(x);splay(x);REV(x)^=1;
	}
	inline int link(int x,int y){
		if(find_root(x)==find_root(y))return 0;
		reverse(x);F(x)=y;return -1;
	}
	inline void cut(int x,int y){
		reverse(x);access(y);splay(y);
		F(LC(y))=0;LC(y)=0;pushup(y);
	}
	inline void update(int x,int val){
		splay(x);tree[x].v=val;pushup(x);
	}
	inline int query(int x,int y){
		if(find_root(x)!=find_root(y))return -1;
		reverse(x);access(y);splay(y);
		return tree[y].sum;
	}
}LCT;
int main(){
	int n=read();
	for(int i=1;i<=n;i++)
		tree[i].v=read();
	int m=read();
	char tp[10];
	while(m--){
		scanf("%s",tp);
		if(tp[0]=='b'){
			int x=read(),y=read();
			if(LCT.link(x,y)==-1)printf("yes\n");
			else printf("no\n");
		}
		else if(tp[0]=='p'){
			int x=read(),val=read();
			LCT.update(x,val);
		}
		else{
			int x=read(),y=read(),ans=LCT.query(x,y);
			if(ans==-1)printf("impossible\n");
			else printf("%d\n",ans);
		}
	}
	return 0;
}



發佈了83 篇原創文章 · 獲贊 27 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章