记录编号 373530 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 Gravatarrewine 是否通过 通过
代码语言 C++ 运行时间 4.714 s
提交时间 2017-02-21 10:16:06 内存使用 67.27 MiB
显示代码纯文本
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <bitset>

using namespace std;

typedef long long LL;

void read(int &x) {
    char c;bool flag = 0;
    while((c=getchar())<'0'||c>'9') flag |= (c=='-');
    x=c-'0';while((c=getchar())>='0'&&c<='9') x = x*10+c-'0';
    flag?x=-x:x;
}

#define N 30100
#define W 10000
/////////////////////////////////////
struct E {
	int to,next;
	E(int to = 0,int next = 0):to(to),next(next){}
} g[N<<1];
int fr[N],tot,id[N],idd,n,w[N],siz[N],fa[N];
//
int M,rt[N*5];
//
int cnt;
struct Node{int lch,rch,sum;}t[N*200];
//
void AddE(int from,int to) {
	g[++tot] = E(to,fr[from]);
	fr[from] = tot;
}

void dfs(int t) {
	id[t] = ++idd; siz[t] = 1;
	for (int i = fr[t]; i; i = g[i].next) {
		int to = g[i].to;
		if(to == fa[t]) continue;
		fa[to] = t;
		dfs(to); siz[t] += siz[to];
	}
}
//////////////////////////////////////
void u2_add(int l,int r,int &o,int v,int x) {
	if(!o) o = ++cnt;
//cout<<l<<" "<<r<<" "<<o<<"\n";
	if(l == r) {t[o].sum += v; return;}
	int mid = (l+r)>>1;
	x <= mid ? u2_add(l,mid,t[o].lch,v,x):u2_add(mid+1,r,t[o].rch,v,x);
	t[o].sum = t[t[o].lch].sum + t[t[o].rch].sum;
}

int q2_sum(int l,int r,int o,int x,int y) {
	if(!o) return 0;
	if(x <= l && r <= y) return t[o].sum;
	int ans = 0,mid = (l+r)>>1;
	if(x <= mid) ans += q2_sum(l,mid,t[o].lch,x,y);
	if(y > mid) ans += q2_sum(mid+1,r,t[o].rch,x,y);
	return ans;
}

//
void build1() {
    for(M = 1; M <= n+1; M <<= 1);
    for(int i = 1; i <= M+n+1; ++i) rt[i] = i;
    cnt = M+n+1;
}

int sum(int l,int r,int L,int R,int ans = 0) {
//cout<<"S"<<l<<" "<<r<<" "<<L<<" "<<R<<"\n";
	for (l = M+l-1,r = M+r+1; l^r^1; l>>=1,r>>=1) {
		if(~l&1) ans += q2_sum(1,W,rt[l^1],L,R);
		if(r&1) ans += q2_sum(1,W,rt[r^1],L,R);
	}
	return ans;
}


int replace(int pos,int w1,int w2) {
	pos += M;
	while(pos) {
		if(w1!=-1) u2_add(1,W,rt[pos],-1,w1);
		u2_add(1,W,rt[pos],1,w2);
		pos >>= 1;
	}
}

int kth(int L,int R,int k) {
//cout<<"kth "<<L<<" "<<R<<" "<<k<<"\n";
	int ans,l = 1,r = W;
	for (;;) {
		if(r-l <= 1) {
		   ans = (sum(L,R,1,l)==k?l:r);
		   break;
		}
		int mid = (l+r)>>1;
		sum(L,R,1,mid) < k ? l = mid : r = mid;
	}
//cout<<sum(L,R,1,8);
	return ans;
}
//

int main() {
    freopen("hjtree.in","r",stdin);freopen("hjtree.out","w",stdout);
	read(n);int u,v,x,y;
	for (int i = 1; i <= n; ++i) read(w[i]);
	for (int i = 1; i < n; ++i) {
		read(u);  read(v);
		AddE(u,v); AddE(v,u);
	}
	dfs(1);	build1();
	for (int i = 1; i <= n; i++) replace(id[i],-1,w[i]);
//for (int i = 1; i <= n; i++) cout<<id[i]<<" ";
//puts("");
	int Q,cas; read(Q);
	for (int i = 1; i <= Q; i++) {
		read(cas); read(u); read(x);
		if(cas == 1) printf("%d\n",kth(id[u],id[u]+siz[u]-1,x));
		else if(cas == 2) read(y),printf("%d\n",sum(id[u],id[u]+siz[u]-1,x,y));
		else replace(id[u],w[u],x),w[u] = x;
	}
    return 0;
}
/*
5
3 4 6 1 2
1 2
1 3
3 4
3 5
7
3 4 5
3 5 7
1 3 3
*/