处理出每个节点到根节点的node[u]值,对于修改操作相当于对子树中的node值修改,查找时查找子树的最大值即可.
dfs序转化成区间操作,线段树查找最大值.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
#define me(a,x) memset(a,x,sizeof(a))
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
#define sc scanf
#define itn int
#define STR clock_t startTime = clock();
#define END clock_t endTime = clock();cout << double(endTime - startTime) / CLOCKS_PER_SEC *1000<< "ms" << endl;
using namespace std;
const int N=1e5+225;
const long long mod=1e9+7;
const long long mod2=998244353;
const int oo=0x7fffffff;
const int sup=0x80000000;
typedef long long ll;
typedef unsigned long long ull;
template <typename it>void db(it *begin,it *end){while(begin!=end)cout<<(*begin++)<<" ";puts("");}
template <typename it>
string to_str(it n){string s="";while(n)s+=n%10+'0',n/=10;reverse(s.begin(),s.end());return s;}
template <typename it>int o(it a){cout<<a<<endl;return 0;}
inline ll mul_64(ll x,ll y,ll c){return (x*y-(ll)((long double)x/c*y)*c+c)%c;}
inline ll ksm(ll a,ll b,ll c){ll ans=1;for(;b;b>>=1,a=a*a%c)if(b&1)ans=ans*a%c;return ans;}
inline void exgcd(ll a,ll b,ll &x,ll &y){if(!b)x=1,y=0;else exgcd(b,a%b,y,x),y-=x*(a/b);}
int n,m,pos[N];
ll node[N],a[N],MAX[N<<2|1],tag[N<<2|1];
vector<int>g[N];
int in[N],out[N],tot=0;
void dfs(int u,int fa){
node[u]+=node[fa];
in[u]=++tot;
pos[tot]=u;
for(int v:g[u]){
if(v==fa)continue;
dfs(v,u);
}
out[u]=tot;
}
void tree(int l,int r,int rt){
tag[rt]=0;
if(l>=r){
MAX[rt]=node[pos[l]];
return ;
}
int mid=l+r>>1;
tree(l,mid,rt<<1);
tree(mid+1,r,rt<<1|1);
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void pu(int rt){
if(tag[rt]!=0){
MAX[rt<<1]+=tag[rt];
MAX[rt<<1|1]+=tag[rt];
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
}
tag[rt]=0;
}
void ins(int l,int r,int rt,int L,int R,int val){
if(L<=l&&r<=R){
MAX[rt]+=val;
tag[rt]+=val;
return ;
}
pu(rt);
int mid=l+r>>1;
if(mid>=L)ins(l,mid,rt<<1,L,R,val);
if(mid<R)ins(mid+1,r,rt<<1|1,L,R,val);
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
ll Q(int l,int r,int rt,int L,int R){
if(L<=l&&r<=R)return MAX[rt];
pu(rt);
int mid=l+r>>1;
ll M=-1e18;
if(mid>=L)M=max(M,Q(l,mid,rt<<1,L,R));
if(mid<R)M=max(M,Q(mid+1,r,rt<<1|1,L,R));
return M;
}
int main(){
int t;cin>>t;
for(int cas=1;cas<=t;cas++){
tot=0;
sc("%d%d",&n,&m);
for(int i=0;i<=n+5;i++)g[i].clear();
for(int i=1;i<n;i++){
int u,v;
sc("%d%d",&u,&v);
u++,v++;
g[u].push_back(v);
g[v].push_back(u);
}
for(int i=1;i<=n;i++)sc("%lld",node+i),a[i]=node[i];
dfs(1,0);
tree(1,n,1);
printf("Case #%d:\n",cas);
while(m--){
int op;sc("%d",&op);
if(op==0){
int x,y;
sc("%d%d",&x,&y);x++;
y-=a[x];a[x]+=y;
ins(1,n,1,in[x],out[x],y);
}else{
int x;sc("%d",&x);x++;
printf("%lld\n",Q(1,n,1,in[x],out[x]));
}
}
}
}
京公网安备 11010502036488号