记录编号 463562 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 GravatarHzoi_Mafia 是否通过 通过
代码语言 C++ 运行时间 2.073 s
提交时间 2017-10-24 13:37:37 内存使用 115.44 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
inline int read(){
	int sum(0);char ch(getchar());
	for(;ch<'0'||ch>'9';ch=getchar());
	for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
	return sum;
}
struct edge{
	int e;edge *n;
}*pre[30005];
inline void insert(int s,int e){edge *tmp(new edge);tmp->e=e;tmp->n=pre[s];pre[s]=tmp;}
int n,q,cnt,timee;
int w[30005],l[30005],r[30005],pos[30005];
inline void dfs(int u,int fa){
	l[u]=++timee;pos[timee]=u;
	for(edge *i=pre[u];i;i=i->n)if(i->e!=fa)dfs(i->e,u);
	r[u]=timee;
}
int root[30005],lch[10000005],rch[10000005],sum[10000005],a,b,L[30],R[30],size(10000);
inline int lowbit(int x){return x&-x;}
inline void update(int &x,int las,int pos,int w,int l,int r){
	x=++cnt;lch[x]=lch[las];rch[x]=rch[las];sum[x]=sum[las]+w;
	if(l==r)return;int mid((l+r)>>1);
	if(pos<=mid)update(lch[x],lch[las],pos,w,l,mid);
	else update(rch[x],rch[las],pos,w,mid+1,r);
}
inline int query(int l,int r,int k){
	if(l==r)return l;
	int mid((l+r)>>1),suml(0),sumr(0);
	for(int i=1;i<=a;++i)suml+=sum[lch[L[i]]];
	for(int i=1;i<=b;++i)sumr+=sum[lch[R[i]]];
	if(k<=sumr-suml){
		for(int i=1;i<=a;++i)L[i]=lch[L[i]];
		for(int i=1;i<=b;++i)R[i]=lch[R[i]];
		return query(l,mid,k);
	}
	else{
		for(int i=1;i<=a;++i)L[i]=rch[L[i]];
		for(int i=1;i<=b;++i)R[i]=rch[R[i]];
		return query(mid+1,r,k-(sumr-suml));
	}
}
inline int query_sum(int ll,int rr,int l,int r){
	if(ll<=l&&r<=rr){
		int ret(0);
		for(int i=1;i<=b;++i)ret+=sum[R[i]];
		for(int i=1;i<=a;++i)ret-=sum[L[i]];
		return ret;
	}
	int tmpl[30],tmpr[30];
	int mid((l+r)>>1),ret(0);
	for(int i=1;i<=a;++i)tmpl[i]=L[i];
	for(int i=1;i<=b;++i)tmpr[i]=R[i];
	if(ll<=mid){
		for(int i=1;i<=a;++i)L[i]=lch[L[i]];
		for(int i=1;i<=b;++i)R[i]=lch[R[i]];
		ret+=query_sum(ll,rr,l,mid);
	}
	if(mid<rr){
		for(int i=1;i<=a;++i)L[i]=rch[tmpl[i]];
		for(int i=1;i<=b;++i)R[i]=rch[tmpr[i]];
		ret+=query_sum(ll,rr,mid+1,r);
	}
	for(int i=1;i<=a;++i)L[i]=tmpl[i];
	for(int i=1;i<=b;++i)R[i]=tmpr[i];
	return ret;
}
int main(){
	freopen("hjtree.in","r",stdin);
	freopen("hjtree.out","w",stdout);
	n=read();
	for(int i=1;i<=n;++i)w[i]=read();
	for(int i=1;i<n;++i){int x(read()),y(read());insert(x,y);insert(y,x);}
	dfs(1,0);
	for(int i=1;i<=n;++i)
		for(int j=i;j<=n;j+=lowbit(j))
			update(root[j],root[j],w[pos[i]],1,1,size);
	q=read();
	while(q--){
		int op(read());
		if(op==1){
			int x(read()),y(read());
			a=b=0;
			for(int i=l[x]-1;i;i-=lowbit(i))L[++a]=root[i];
			for(int i=r[x];i;i-=lowbit(i))R[++b]=root[i];
			printf("%d\n",query(1,size,y));
		}
		if(op==2){
			int x(read()),y(read()),z(read());a=b=0;
			for(int i=l[x]-1;i;i-=lowbit(i))L[++a]=root[i];
			for(int i=r[x];i;i-=lowbit(i))R[++b]=root[i];
			printf("%d\n",query_sum(y,z,1,size));
		}
		if(op==3){
			int x(read()),y(read());
			for(int i=l[x];i<=n;i+=lowbit(i))update(root[i],root[i],w[x],-1,1,size);
			w[x]=y;
			for(int i=l[x];i<=n;i+=lowbit(i))update(root[i],root[i],y,1,1,size);
		}
	}
}