[HAOI2015]树上操作 -树链剖分
来源:互联网 发布:sql server 查询二进制 编辑:程序博客网 时间:2024/05/21 10:14
1963. [HAOI2015]树上操作代码
【题目描述】
有一棵点数为N的树,以点1为根,且树点有权值。然后有M个操作,分为三种:
操作1:把某个节点x的点权增加a。
操作2:把某个节点x为根的子树中所有点的点权都增加a。
操作3:询问某个节点x到根的路径中所有点的点权和。
【输入格式】
第一行两个整数N,M,表示点数和操作数。
接下来一行N个整数,表示树中节点的初始权值。
接下来N-1行每行两个正整数fr,to,表示该树中存在一条边(fr,to)。
再接下来M行,每行分别表示一次操作。其中第一个数表示该操作的种类(1~3),之后接这个操作的参数(x或者x a)。
【输出格式】
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
【样例输入】
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
【样例输出】
6
9
13
【提示】
对于30%的数据,N,M<=1000
对于50%的数据,N,M<=100000且数据随机。
对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。
注意long long就好了
把它当做树剖模板来做,听说并查集也能做
1 #include <ctype.h> 2 #include <cstdio> 3 4 typedef long long LL; 5 6 const int MAXN=100010; 7 8 int n,m,inr; 9 10 LL a[MAXN]; 11 12 struct SegmentTree { 13 int l,r; 14 LL val,tag; 15 }; 16 SegmentTree t[MAXN<<2]; 17 18 struct data { 19 int to; 20 int next; 21 }; 22 data E[MAXN*10]; 23 24 int head[MAXN<<1],tot; 25 26 int siz[MAXN],son[MAXN],fa[MAXN],id[MAXN],dep[MAXN],top[MAXN],rank[MAXN],mx[MAXN]; 27 28 inline void read(int&x) { 29 int f=1;register char c=getchar(); 30 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 31 for(;isdigit(c);x=x*10+c-48,c=getchar()); 32 x=x*f; 33 } 34 35 inline void readl(LL&x) { 36 int f=1;register char c=getchar(); 37 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 38 for(;isdigit(c);x=x*10+c-48,c=getchar()); 39 x=x*f; 40 } 41 42 inline void add(int x,int y) { 43 E[++tot].to=y; 44 E[tot].next=head[x]; 45 head[x]=tot; 46 } 47 48 inline int max(int a,int b) { 49 return a<b?b:a; 50 } 51 52 inline void swap(int&x,int&y) { 53 int t=x;x=y;y=t; 54 return; 55 } 56 57 inline void dfs_1(int now,int f) { 58 dep[now]=dep[f]+1; 59 siz[now]=1; 60 fa[now]=f; 61 for(register int i=head[now];i;i=E[i].next) { 62 int to=E[i].to; 63 if(to==f) continue; 64 dfs_1(to,now); 65 siz[now]+=siz[to]; 66 if(son[now]==-1||siz[son[now]]<siz[to]) son[now]=to; 67 } 68 } 69 70 inline void dfs_2(int now,int sym) { 71 id[now]=++inr; 72 top[now]=sym; 73 rank[id[now]]=now; 74 if(son[now]==-1) return; 75 dfs_2(son[now],sym); 76 for(int i=head[now];i;i=E[i].next) { 77 int to=E[i].to; 78 if(to!=son[now]&&to!=fa[now]) 79 dfs_2(to,to); 80 } 81 return; 82 } 83 84 inline void build_tree(int now,int l,int r) { 85 t[now].l=l,t[now].r=r; 86 if(l==r) { 87 t[now].val=a[rank[l]]; 88 return; 89 } 90 int mid=(l+r)>>1; 91 build_tree(now<<1,l,mid); 92 build_tree(now<<1|1,mid+1,r); 93 t[now].val=t[now<<1].val+t[now<<1|1].val; 94 } 95 96 inline void down(int now) { 97 t[now<<1].val+=(t[now<<1].r-t[now<<1].l+1)*t[now].tag; 98 t[now<<1|1].val+=(t[now<<1|1].r-t[now<<1|1].l+1)*t[now].tag; 99 t[now<<1].tag+=t[now].tag;100 t[now<<1|1].tag+=t[now].tag;101 t[now].tag=0;102 }103 104 inline void modify(int now,int l,int r,LL val) {105 if(l<=t[now].l&&r>=t[now].r) {106 t[now].tag+=val;107 t[now].val+=(t[now].r-t[now].l+1)*val;108 return;109 }110 down(now);111 int mid=(t[now].l+t[now].r)>>1;112 if(l<=mid) modify(now<<1,l,r,val);113 if(r>mid) modify(now<<1|1,l,r,val);114 t[now].val=t[now<<1].val+t[now<<1|1].val;115 }116 117 inline LL query(int now,int l,int r) {118 LL ans=0;119 if(l<=t[now].l&&r>=t[now].r) return t[now].val;120 down(now);121 int mid=(t[now].l+t[now].r)>>1;122 if(l<=mid) ans+=query(now<<1,l,r);123 if(r>mid) ans+=query(now<<1|1,l,r);124 return ans;125 }126 127 inline LL Pre_query(int u,int v) {128 LL ans=0;129 while(top[u]!=top[v]) {130 if(dep[top[u]]<dep[top[v]]) swap(u,v);131 ans+=query(1,id[top[u]],id[u]);132 u=fa[top[u]];133 }134 if(dep[u]<dep[v]) swap(u,v);135 ans+=query(1,id[v],id[u]);136 return ans;137 }138 139 int hh() {140 freopen("haoi2015_t2.in","r",stdin);141 freopen("haoi2015_t2.out","w",stdout);142 int x,y,opt;143 read(n);read(m);144 for(register int i=1;i<=n;++i) son[i]=-1,readl(a[i]);145 for(register int i=1;i<n;++i) {146 read(x);read(y);147 add(x,y);add(y,x);148 }149 dfs_1(1,0);150 dfs_2(1,1);151 build_tree(1,1,inr);152 LL p;153 for(register int i=1;i<=m;++i) {154 read(opt);read(x);155 if(opt==1) {156 readl(p);157 modify(1,id[x],id[x],p);158 }159 else if(opt==2) {160 readl(p);161 modify(1,id[x],id[x]+siz[x]-1,p);162 }163 else {164 LL ans=Pre_query(1,x);165 printf("%lld\n",ans);166 }167 }168 return 0;169 }170 171 int sb=hh();172 int main() {;}
阅读全文
0 0
- [HAOI2015]树上操作 -树链剖分
- 【bzoj4034】【HAOI2015】【树上操作】【树链剖分】
- 【HAOI2015】树上操作(树链剖分)
- bzoj4034 [HAOI2015]树上操作(树链剖分)
- 【树链剖分】bzoj4034: [HAOI2015]树上操作
- bzoj 4034: [HAOI2015]树上操作 (树链剖分)
- 【BZOJ】4034 [HAOI2015]树上操作 树链剖分
- BZOJ 4034 [HAOI2015]树上操作 树链剖分
- 【BZOJ4034】树上操作(HAOI2015)-树链剖分
- bzoj 4034: [HAOI2015]树上操作 树链剖分
- [HAOI2015]树上操作
- bzoj4034 [HAOI2015]树上操作
- 【bzoj4034】[HAOI2015]树上操作
- BZOJ4034: [HAOI2015]树上操作
- [bzoj4034][HAOI2015]树上操作
- 4034: [HAOI2015]树上操作
- bzoj4034: [HAOI2015]树上操作
- 【BZOJ4034】【HAOI2015】树上操作
- P2420 让我们异或吧
- 51Nod 1526 分配 笔名
- 图书管理系统full-stack总结
- [USACO09JAN]安全出行Safe Travel
- HDU Aragorn's Story -树链剖分
- [HAOI2015]树上操作 -树链剖分
- hdu4965——矩阵快速幂优化
- [SCOI2007]kshort--k短路
- Spark错误 Exception: Java gateway process exited before sending the driver its port number
- POJ 2449 Remmarguts' Date -K短路
- [SDOI2010]魔法猪学院 --k短路
- [ZJOI2008]树的统计Count
- [USACO Mar08] 牛跑步 --k短路
- [POJ3255] 地砖RoadBlocks