记录编号 373414 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 5.103 s
提交时间 2017-02-21 06:36:50 内存使用 148.31 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=30010;
struct node{
	int sm;
	node *lc,*rc;
	node():sm(0){}
}null[maxn*450],*ptr=null,*root[maxn<<2];
void dfs(int);
void add(int,int,int);
void qsum(int,int,int);
void kth(int,int,int);
void add(int,int,node*&);
void qsum(int,int,node*);
vector<int>G[maxn];
int p[maxn],dfn[maxn],finish[maxn],tim=0;
int n,m,w[maxn],x,y,s,t,a,b,k,d,tmp;
int main(){
	freopen("hjtree.in","r",stdin);
	freopen("hjtree.out","w",stdout);
	null->lc=null->rc=null;
	fill(root,root+(maxn<<2),(node*)null);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	d=1;
	dfs(1);
	scanf("%d",&m);
	while(m--){
		scanf("%d%d",&d,&x);
		if(d==1){
			scanf("%d",&k);
			s=dfn[x];
			t=finish[x];
			kth(1,10000,1);
			printf("%d\n",tmp);
		}
		else if(d==2){
			scanf("%d%d",&a,&b);
			s=dfn[x];
			t=finish[x];
			tmp=0;
			qsum(1,10000,1);
			printf("%d\n",tmp);
		}
		else{
			d=-1;
			y=w[x];
			k=dfn[x];
			add(1,10000,1);
			scanf("%d",&y);
			d=1;
			add(1,10000,1);
			w[x]=y;
		}
	}
	return 0;
}
void dfs(int x){
	k=dfn[x]=++tim;
	y=w[x];
	add(1,10000,1);
	for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=p[x]){
		p[G[x][i]]=x;
		dfs(G[x][i]);
	}
	finish[x]=tim;
}
void add(int l,int r,int rt){
	add(1,n,root[rt]);
	if(l==r)return;
	int mid=(l+r)>>1;
	if(y<=mid)add(l,mid,rt<<1);
	else add(mid+1,r,rt<<1|1);
}
void qsum(int l,int r,int rt){
	if(a<=l&&b>=r){
		qsum(1,n,root[rt]);
		return;
	}
	int mid=(l+r)>>1;
	if(a<=mid)qsum(l,mid,rt<<1);
	if(b>mid)qsum(mid+1,r,rt<<1|1);
}
void kth(int l,int r,int rt){
	if(l==r){
		tmp=l;
		return;
	}
	int mid=(l+r)>>1;
	tmp=0;
	qsum(1,n,root[rt<<1]);
	if(k<=tmp)kth(l,mid,rt<<1);
	else{
		k-=tmp;
		kth(mid+1,r,rt<<1|1);
	}
}
void add(int l,int r,node *&rt){
	if(rt==null){
		rt=++ptr;
		rt->lc=rt->rc=null;
	}
	rt->sm+=d;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(k<=mid)add(l,mid,rt->lc);
	else add(mid+1,r,rt->rc);
}
void qsum(int l,int r,node *rt){
	if(rt==null)return;
	if(s<=l&&t>=r){
		tmp+=rt->sm;
		return;
	}
	int mid=(l+r)>>1;
	if(s<=mid)qsum(l,mid,rt->lc);
	if(t>mid)qsum(mid+1,r,rt->rc);
}
/*
5
3 4 6 1 2
1 2
1 3
3 4
3 5
7
1 1 4
2 1 1 5
3 4 5
1 1 4
2 3 3 6
3 5 7
1 3 3
*/