标签:max 查询 build lang -- return solution poj php
我太难了
\(HDU\) 卡前向星 , \(POJ\) 卡 \(vector\)
我真的是服了
给定一棵树,要求支持如下操作:
\(1.\) 单点修改权值
\(2.\) 查询经过某点的权值和最大的链
其实挺简单的吧,就是先一遍 \(dfs\) 把树上的权值搞个前缀和
然后对 \(dfn\) 建线段树
单点改,区间查
屑题卡我半小时常,我现在也不知为啥链式前向星不对
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
return res*f;
}
inline int max(int x,int y){return x>y?x:y;}
const int N=1e5+10;
int val[N];
struct tree{
int l,r,maxx,add;
#define l(p) t[p].l
#define r(p) t[p].r
#define maxx(p) t[p].maxx
#define add(p) t[p].add
}t[N<<2];
vector<int> g[N];
inline void build(int p,int l,int r)
{
l(p)=l; r(p)=r; add(p)=0;
if(l==r) return maxx(p)=val[l],void();
int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r);
maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
return ;
}
inline void spread(int p)
{
if(add(p))
{
maxx(p<<1)+=add(p); maxx(p<<1|1)+=add(p);
add(p<<1)+=add(p); add(p<<1|1)+=add(p);
add(p)=0;
}return ;
}
inline void change(int p,int l,int r,int d)
{
if(l(p)>=l&&r(p)<=r)
{
add(p)+=d; maxx(p)+=d;
return ;
} spread(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid) change(p<<1,l,r,d);
if(r>mid) change(p<<1|1,l,r,d);
maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
return ;
}
inline int ask(int p,int l,int r)
{
if(l<=l(p)&&r(p)<=r) return maxx(p);
spread(p); int mid=(l(p)+r(p))>>1;
int ans=-1e15-10;
if(l<=mid) ans=max(ans,ask(p<<1,l,r));
if(r>mid) ans=max(ans,ask(p<<1|1,l,r));
maxx(p)=max(maxx(p<<1),maxx(p<<1|1));
return ans;
}
int tot,l[N],r[N],p[N],n,m;
inline void dfs(int x,int fa)
{
l[x]=++tot; val[l[x]]=p[x]+val[l[fa]];
int sz=g[x].size();
for(int i=0;i<sz;++i) if(g[x][i]!=fa) dfs(g[x][i],x);
r[x]=tot;
return ;
}
int num;
inline void work()
{
for(int i=1;i<=n;++i) g[i].clear();
memset(t,0,sizeof(t)); memset(val,0,sizeof(val));
memset(l,0,sizeof(l)); memset(r,0,sizeof(r));
++num; tot=0;
printf("Case #%lld:\n",num);
n=read(); m=read();
for(int i=1;i<n;++i)
{
int u=1+read(),v=1+read();
g[u].push_back(v); g[v].push_back(u);
}
for(int i=1;i<=n;++i) p[i]=read();
dfs(1,0); build(1,1,n);
while(m--)
{
int opt=read();
if(opt==1)
{
int x=read()+1;
printf("%lld\n",ask(1,l[x],r[x]));
}
else
{
int x=read()+1,y=read();
change(1,l[x],r[x],y-p[x]);
p[x]=y;
}
}
return ;
}
signed main()
{
int T=read(); while(T--) work();
return 0;
}
}
signed main(){return yspm::main();}
标签:max 查询 build lang -- return solution poj php
原文地址:https://www.cnblogs.com/yspm/p/12657722.html