bzoj4034 cogs1963 [HAOI2015]树上操作
来源:互联网 发布:stl stack源码 编辑:程序博客网 时间:2024/06/04 17:42
dfs序+线段树
先求出每个点的出栈入栈时间
然后用线段树去维护
入栈为正出栈为负
那么区间和就可以表示一个子树的和
操作1是简单的单点修改
操作2是简单的区间修改
对于操作3 我们可以发现 从根到一个点的路径在dfs序上是连续的一段 那么我们直接查询1到in[x]就可以了
听说这道题分块也可以做? 没有考虑 另外就是树剖也可以做这道题
#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const long long N=400005;long long n=0,m=0;long long a[N],b[N];long long head[N],next[N*2],to[N*2],edge=0;long long t=0,in[N],out[N];long long isIn[N];long long flag[N<<2];LL sum[N<<2],plus[N<<2];inline void addEdge(long long u,long long v) { to[edge]=v,next[edge]=head[u],head[u]=edge++; to[edge]=u,next[edge]=head[v],head[v]=edge++; }void dfs(long long x,long long fa) { b[in[x]=++t]=a[x]; isIn[t]=1; for (long long e=head[x];~e;e=next[e]) { long long v=to[e]; if (v!=fa) dfs(v,x); } b[out[x]=++t]=-a[x]; isIn[t]=0; }inline void pushUp(long long rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; }inline void pushDown(long long rt) { if (plus[rt]) { sum[rt<<1]+=flag[rt<<1]*plus[rt]; sum[rt<<1|1]+=flag[rt<<1|1]*plus[rt]; plus[rt<<1]+=plus[rt]; plus[rt<<1|1]+=plus[rt]; plus[rt]=0; } }void build(long long rt,long long l,long long r) { if (l==r) { flag[rt]=isIn[l]?1:-1; sum[rt]=b[l]; } else { long long mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); flag[rt]=flag[rt<<1]+flag[rt<<1|1]; pushUp(rt); }}void update(long long rt,long long l,long long r,long long l0,long long r0,long long val) { if (l0<=l && r<=r0) { plus[rt]+=val; sum[rt]+=flag[rt]*val; } else { pushDown(rt); long long mid=(l+r)>>1; if (l0<=mid) update(rt<<1,l,mid,l0,r0,val); if (r0>mid) update(rt<<1|1,mid+1,r,l0,r0,val); pushUp(rt); }}LL query(long long rt,long long l,long long r,long long l0,long long r0) { if (l0<=l && r<=r0) { return sum[rt]; } else { pushDown(rt); long long mid=(l+r)>>1; LL ret=0; if (l0<=mid) ret+=query(rt<<1,l,mid,l0,r0); if (r0>mid) ret+=query(rt<<1|1,mid+1,r,l0,r0); return ret; }}int main(void) { freopen("haoi2015_t2.in","r",stdin); freopen("haoi2015_t2.out","w",stdout); memset(head,-1,sizeof(head)); scanf("%lld%lld",&n,&m); for (long long i=1;i<=n;++i) scanf("%lld",a+i); for (long long i=0;i<n-1;++i) { long long u=0,v=0; scanf("%lld%lld",&u,&v); addEdge(u,v); } dfs(1,-1); build(1,1,n<<1); while (m--) { long long type=0,arg1=0; scanf("%lld%lld",&type,&arg1); switch (type) { case 1:{ long long arg2=0; scanf("%lld",&arg2); update(1,1,n<<1,in[arg1],in[arg1],arg2); update(1,1,n<<1,out[arg1],out[arg1],arg2); break; } case 2:{ long long arg2=0; scanf("%lld",&arg2); update(1,1,n<<1,in[arg1],out[arg1],arg2); break; } case 3:{ printf("%lld\n",query(1,1,n<<1,1,in[arg1])); break; } } } fclose(stdin); fclose(stdout); return 0;}
0 0
- bzoj4034 cogs1963 [HAOI2015]树上操作
- bzoj4034 [HAOI2015]树上操作
- 【bzoj4034】[HAOI2015]树上操作
- BZOJ4034: [HAOI2015]树上操作
- [bzoj4034][HAOI2015]树上操作
- bzoj4034: [HAOI2015]树上操作
- 【BZOJ4034】【HAOI2015】树上操作
- bzoj4034 [HAOI2015]树上操作
- bzoj4034: [HAOI2015]树上操作
- BZOJ4034 [HAOI2015]树上操作
- 【bzoj4034】【HAOI2015】【树上操作】【树链剖分】
- 【HAOI2015】【BZOJ4034】树上操作T2
- [题解]bzoj4034 HAOI2015 树上操作
- bzoj4034 [HAOI2015]树上操作(树链剖分)
- 【树链剖分】bzoj4034: [HAOI2015]树上操作
- BZOJ4034——[HAOI2015]树上操作
- 【BZOJ4034】树上操作(HAOI2015)-树链剖分
- BZOJ4034: [HAOI2015]树上操作(洛谷P3178)
- ibatis批量查询(excel批量导出)
- handler
- 拉取人人直播流
- c++中结构体和类的异同
- 静态资源访问问题,springmvc
- bzoj4034 cogs1963 [HAOI2015]树上操作
- SQL高级应用
- 二进制写文件 多出0D
- 空闲时间学一个Linux命令(13)—— less 命令
- hadoop开发环境搭建时出现的一些问题
- 在Spring Boot框架下使用WebSocket实现聊天功能
- Presto集群安装配置
- 沉思
- Myeclipse出现the jar file xxx.jar has no source attachment. 问题