记录编号 373407 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 Gravatar可以的. 是否通过 通过
代码语言 C++ 运行时间 4.137 s
提交时间 2017-02-21 06:22:32 内存使用 1.80 MiB
显示代码纯文本
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <ctime>
#define Mem(a, v) memset(a, v, sizeof a)
#define Mcpy(a, b) memcpy(a, b, sizeof a)
using namespace std;
typedef long long LL;
const int maxn = 30010;
#define lc rt<<1
#define rc rt<<1|1
#define mid (((l)+(r))>>(1))
#define lson lc,l,mid
#define rson rc,mid+1,r
void qkin(int &res){
	int x,f=1; char ch;
	while(ch=getchar(),ch<'0'||ch>'9')if(ch=='-')f=-1;x=ch-48;
	while(ch=getchar(),ch>='0'&&ch<='9')x=x*10+ch-48;res=x*f;
}
void read(int &A){ qkin(A); }
void read(int &A,int &B){ qkin(A),qkin(B); }
void read(int &A,int &B,int &C){ qkin(A),qkin(B),qkin(C); }
void read(int &A,int &B,int &C,int &D)
{ qkin(A),qkin(B),qkin(C),qkin(D); }

int n,len,head[maxn],m,w[maxn];
struct Edge
{
	int to,next;
}e[maxn*2];
void insert(int x,int y){
	e[++len].to = y;
	e[len].next = head[x];
	head[x] = len;  
}
int dfn[maxn],pos[maxn],cnt,ra[maxn];
void Dfs(int x){
	dfn[x] = ++cnt; pos[cnt] = x;
	for(int i = head[x]; i; i = e[i].next){
		int p = e[i].to;
		if(!dfn[p]) Dfs(p);
	}
	ra[x] = cnt;
}

#define siz(x) ((x)?((x)->size):(0))
struct node
{
	int data, size, key;
	node *ch[2];
	node(int d): data(d), size(1), key(rand()){}
	void ref(){ size=siz(ch[0])+siz(ch[1])+1; }
}*root[maxn*4];
node* newnode(int);
void insert(int,node*&);
void del(int,node*&);
void rot(node*&,int);
int rank(int,node*);

void insert(int i,int x,int rt,int l,int r){
	insert(x, root[rt]);
	if(l == r) return;
	if(i<=mid) insert(i,x,lson);
	else       insert(i,x,rson);
}
void del(int i,int x,int rt,int l,int r){
	del(x, root[rt]);
	if(l == r) return;
	if(i<=mid) del(i,x,lson);
	else       del(i,x,rson);
}
int getrank(int s,int t,int x,int rt,int l,int r){
	if(s<=l && t>=r) return rank(x, root[rt]);
	if(t<=mid) return getrank(s,t,x,lson);
	if(s> mid) return getrank(s,t,x,rson);
	return getrank(s,t,x,lson)+getrank(s,t,x,rson);
}
void Build_tree_in_tree(){
	for(int i = 1; i <= n; i ++ )
		insert(i, w[pos[i]], 1, 1, n);
}
void Query(int s,int t,int k){
	int l = 1, r = 10000, ans;
	while(l <= r){
		ans = (l + r) >> 1;
		if(getrank(s,t,ans,1,1,n)+1 <= k) l = ans+1;
		else r = ans-1;
	}//r
	printf("%d\n", r);
}
void Query(int s,int t,int a,int b){
	int ans = 0;
	ans += getrank(s, t, b+1, 1, 1, n);
	ans -= getrank(s, t, a, 1, 1, n);
	printf("%d\n", ans);
}
int main(){
#define HAHA LALA
#ifdef HAHA
	freopen("hjtree.in","r",stdin);
	freopen("hjtree.out","w",stdout);
#endif
	srand(time(NULL));
	read(n);
	for(int i = 1; i <= n; i ++ ) read(w[i]);
	for(int i = 1; i < n; i ++ ){
		int x,y; read(x, y); 
		insert(x, y); insert(y, x);
	}
	Dfs(1);
	Build_tree_in_tree();
	read(m);
	int op, u, a, b;
	while(m--){
		read(op, u, a);
		if(op == 2) read(b);
		if(op == 1)	Query(dfn[u], ra[u], a);
		else if(op == 2) Query(dfn[u], ra[u], a, b);
		else {
			del(dfn[u], w[u], 1, 1, n);
			insert(dfn[u], a, 1, 1, n);
			w[u] = a;
		}
	}
	return 0;
}
node* newnode(int x){
	node *y = new node(x); 
	y->ch[0] = y->ch[1] = NULL;
	return y;
}
void insert(int x,node* &rt){
	if(!rt){ rt = newnode(x); return; }
	else {
		int d = (x < rt->data);
		insert(x, rt->ch[d^1]);
		rt->ref();
		if(rt->ch[d^1]->key > rt->key) rot(rt, d);
	}
}
void del(int x,node* &rt){
	if(x == rt->data){
		if(rt->ch[0] && rt->ch[1]){
			int d = (rt->ch[0]->key > rt->ch[1]->key);
			rot(rt, d); del(x, rt->ch[d]);
		} else {
			node *y = NULL;
			if(rt->ch[0]) y=rt->ch[0];
			else y=rt->ch[1];
			delete rt; rt = y;
		}
	}
	else del(x, rt->ch[(x<rt->data)^1]);
	if(rt) rt->ref();
}
void rot(node* &x,int d){
	node *y = x->ch[d^1];
	x->ch[d^1] = y->ch[d];
	y->ch[d] = x;
	x->ref(); y->ref();
	x = y;
}
int rank(int x,node* rt){
	int d = 0;
	while(rt){
		if(x <= rt->data) rt=rt->ch[0];
		else {
			d += siz(rt->ch[0])+1;
			rt=rt->ch[1];
		}
	}
	return d;
}