hdu5044 Tree(树链剖分+差分)
来源:互联网 发布:英语课文朗读软件 编辑:程序博客网 时间:2024/05/22 00:25
线段树会T,要用O(n)的区间修改+单点查询,也就是像差值似的,把区间修改变成点修改,最后前缀和就是每个点的值。(可是我这样还是差点T掉了o(╥﹏╥)o)
#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define N 100010inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}int n,m,p[N],h[N],num,dep[N],fa[N],son[N],size[N],top[N],id[N],dfn;ll ans1[N],ans2[N];struct edge{ int to,next,val;}data[N<<1];void dfs1(int x){ size[x]=1; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(fa[x]==y) continue; fa[y]=x;dep[y]=dep[x]+1;p[i>>1]=y; dfs1(y);size[x]+=size[y]; if(size[y]>size[son[x]]) son[x]=y; }}void dfs2(int x,int tp){ id[x]=++dfn;top[x]=tp; if(son[x]) dfs2(son[x],tp); for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(y==fa[x]||y==son[x]) continue;dfs2(y,y); }}void doadd1(int x,int y,int val){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ans1[id[top[x]]]+=val,ans1[id[x]+1]-=val; x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y); ans1[id[x]]+=val;ans1[id[y]+1]-=val;}void doadd2(int x,int y,int val){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ans2[id[top[x]]]+=val,ans2[id[x]+1]-=val; x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return; ans2[id[x]+1]+=val;ans2[id[y]+1]-=val;}int main(){// freopen("a.in","r",stdin); int t=read(); for(int tt=1;tt<=t;++tt){ printf("Case #%d:\n",tt);n=read();m=read(); memset(h,0,sizeof(h));memset(fa,0,sizeof(fa)); memset(son,0,sizeof(son));dfn=0;num=1; memset(ans1,0,sizeof(ans1));memset(ans2,0,sizeof(ans2)); for(int i=1;i<n;++i){ int x=read(),y=read(); data[++num].to=y;data[num].next=h[x];h[x]=num; data[++num].to=x;data[num].next=h[y];h[y]=num; } dep[1]=1;dfs1(1);dfs2(1,1); while(m--){ char op[6];scanf("%s",op);int x=read(),y=read(),z=read(); if(op[3]=='1') doadd1(x,y,z); else doadd2(x,y,z); } for(int i=1;i<=n;++i){ans1[i]+=ans1[i-1];ans2[i]+=ans2[i-1];} for(int i=1;i<=n;++i){ if(i==n) printf("%lld\n",ans1[id[i]]); else printf("%lld ",ans1[id[i]]); } for(int i=1;i<n;++i){ if(i==n-1) printf("%lld\n",ans2[id[p[i]]]); else printf("%lld ",ans2[id[p[i]]]); } if(n==1) puts(""); } return 0;}
阅读全文
0 0
- hdu5044 Tree(树链剖分+差分)
- HDU5044--Tree(树链剖分)
- HDU5044 Tree(树链剖分)
- HDU5044【LCA+差分】
- hdu5044(神姿势+树链剖分)
- 树链剖分+离散+扫描(HDU5044)
- HDU 5044 Tree 树链剖分+差分
- hdu5044 Tree 树链剖分,点剖分,边剖分,非递归版
- hdu3966 or hdu5044 树链剖分
- 2014上海网络预选赛1003(树链剖分)HDU5044
- hdu5044(树链剖分+标记法实现区间更新)
- bzoj1651(差分)
- HDU5044 2014上海网络赛1003 tree
- 739B Codeforces Alyona and a tree 树上差分+二分(倍增)
- Codeforces 739B Alyona and a tree (树上差分+二分)
- bzoj 3631 树链剖分+差分
- ZOJ1508 (差分约束)
- hdu3592(差分约束)
- 406
- 对java中map学习笔记整理
- uva 11729 突击队(训练思维+贪心)
- 面试必备之海量数据处理
- 使用HTML语言和CSS开发商业站点_盒子模型
- hdu5044 Tree(树链剖分+差分)
- 精美古诗词集锦
- 关于编译debug和release的方式
- 软件设计原则
- 操作系统-内存管理-内存空间的连续分配方式
- python中is和==
- java序列化
- 2017 ACM/ICPC Asia Regional Shenyang Online Ping Ping Ping 树链剖分+树状数组
- Linux下jdk的安装以及配置