hdu 5044(树链剖分+区间标记小优化)
来源:互联网 发布:50而知天命什么意思 编辑:程序博客网 时间:2024/06/08 10:30
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.
The first line of each case contains two integers N ,M (1 ≤ N, M ≤105),denoting the number of nodes and operations, respectively.
The next N - 1 lines, each lines contains two integers u, v(1 ≤ u, v ≤ N ), denote there is an edge between u,v and its initial value is 0.
For the next M line, contain instructions “ADD1 u v k” or “ADD2 u v k”. (1 ≤ u, v ≤ N, -10 5 ≤ k ≤ 10 5)
The second line contains N integer which means the value of each node.
The third line contains N - 1 integer which means the value of each edge according to the input order.
24 21 22 32 4ADD1 1 4 1ADD2 3 4 24 21 22 31 4ADD1 1 4 5ADD2 3 2 4
Case #1:1 1 0 10 2 2Case #2:5 0 0 50 4 0
题意:一颗n个结点的树,两种操作: 1、将u到v之间的结点权值加k;2、将u到v之间的边权加k。输出经过修改后所有的边权和点权。
点剖和边剖,第一次做边剖,边剖对于点剖的区别
#include <bits/stdc++.h>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")const int maxn=100000+110;#define lowbit(x) (x)&(-x)typedef long long ll;template <class T>bool scan_d(T &ret){ char c; int sgn; T bit = 0.1; if (c=getchar(), c==EOF) { return 0; } while (c!= '-' && c != '.' && (c < '0' || c > '9')) { c = getchar(); } sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'); } if (c == ' ' || c == '\n') { ret *= sgn; return 1; } while (c = getchar(), c >= '0' && c <= '9') { ret += (c - '0') * bit, bit /= 10; } ret *= sgn; return 1;}template <class T>inline void print_d(T x){ if (x > 9) { print_d(x/10); } putchar(x % 10 + '0');}struct sad{ int to,next,id;}G[maxn<<2];int h[maxn],si;void add(int u,int v,int id){ G[si].to=v; G[si].id=id; G[si].next=h[u]; h[u]=si++;}int siz[maxn],dep[maxn];int fa[maxn],son[maxn],top[maxn];int fid[maxn],pos;int p[maxn],fp[maxn];ll sum[maxn],sum1[maxn];void dfs1(int u,int f,int d){ fa[u]=f; dep[u]=d; siz[u]=1; son[u]=-1; for(int i=h[u];~i;i=G[i].next) { int v=G[i].to; if(v^f) { fid[G[i].id]=v; dfs1(v,u,d+1); siz[u]+=siz[v]; if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v; } }}void dfs2(int u,int sf){ top[u]=sf; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1) return; dfs2(son[u],sf); for(int i=h[u];~i;i=G[i].next) { int v=G[i].to; if(son[u]!=v&&fa[u]!=v) dfs2(v,v); }}void init(){ memset(h,-1,sizeof(h)); si=0; pos=1;}void Change1(int u,int v,int val){ int f1=top[u],f2=top[v]; while(f1!=f2){ if(dep[f1]<dep[f2]) { swap(f1,f2); swap(u,v); } sum[p[f1]]+=val; sum[p[u]+1]-=val; u=fa[f1]; f1=top[u]; } if(dep[u]>dep[v]) swap(u,v); sum[p[u]]+=val; sum[p[v]+1]-=val;}void Change2(int u,int v,int val){ int f1=top[u],f2=top[v]; while(f1!=f2){ if(dep[f1]<dep[f2]) { swap(f1,f2); swap(u,v); } sum1[p[f1]]+=val; sum1[p[u]+1]-=val; u=fa[f1]; f1=top[u]; } if(u==v) return ;//边剖,相等的时候退出 if(dep[u]>dep[v]) swap(u,v); sum1[p[son[u]]]+=val;//边剖最后更新的是公共祖先和儿子 sum1[p[v]+1]-=val;}int main(){ int hh,n,q; scanf("%d",&hh); for(int cas=1;cas<=hh;cas++) { scanf("%d%d",&n,&q); int a,b; for(int i=1;i<=n+5;i++) sum[i]=0,sum1[i]=0; init(); for(int i=1;i<=n-1;i++) { scanf("%d%d",&a,&b); add(a,b,i); add(b,a,i); } dfs1(1,0,1); dfs2(1,0); while(q--) { char op[10]; int a,b,val; scanf(" %s",op); scanf("%d%d%d",&a,&b,&val); if(op[3]=='1') Change1(a,b,val); else if(a!=b) Change2(a,b,val); } printf("Case #%d:\n",cas ); for(int i=1;i<=n;i++) sum[i]+=sum[i-1],sum1[i]+=sum1[i-1]; printf("%I64d",sum[p[1]] ); for(int i=2;i<=n;i++) { printf(" %I64d",sum[p[i]]); } printf("\n"); for(int i=1;i<n;i++) { if(i!=1) printf(" "); printf("%I64d",sum1[p[fid[i]]]);//边剖是把边的权值加载边的结束点 } printf("\n"); }}
阅读全文
0 0
- hdu 5044(树链剖分+区间标记小优化)
- hdu 1698 (延迟标记+区间修改+区间求和)
- hdu5044(树链剖分+标记法实现区间更新)
- POJ 3237 Tree(树链剖分 线段树区间标记)
- hdu 3397 Sequence operation (线段树+区间合并+双Lazy标记)
- 杭电 HDU ACM 1698 Just a Hook(线段树 区间更新 延迟标记)
- HDU 1556 Color the ball(区间标记或者线段树)
- HDU 1698 Just a Hook(线段树的区间更新《标记》)
- hdu 5044 Tree (树链剖分+打标记)
- hdu 3397 线段树+区间合并+懒惰标记 好题
- hdu-4587-线段树的区间操作- lazy标记
- hdu 1698 线段树区间更新入门(lazy标记)
- 线段树 (区间修改 区间查询 延迟标记)
- 郁闷的出纳员 (splay的区间标记模板,删除区间,add标记,类似线段树)
- hdu 4509(memset标记)
- 华哥倒酒<区间标记,二分>
- HDU 1728 逃离迷宫 DFS+标记转弯数+优化
- hdu 3506 Monkey Party (区间dp 求环形石子合并+四边形不等式优化)
- poj 1200:Crazy Search (Hash)
- 【学习笔记十】- 使用<canvas>绘图 《js高程》15 笔记
- 【20171002】python_语言设计(4)文件
- ArcGIS for Android Runtime100 基本操作(一)——点线面测距离长度和面积
- 清 · 北 ·Ⅰ
- hdu 5044(树链剖分+区间标记小优化)
- 身份证号信息查询工具
- 使用jreloader实现tomcat中class文件的热部署
- java深入学习十二之文件
- 并查集算法解决Redundant Connection I&II
- a difficult problem FWT 模板
- runtime 简单的介绍
- idea搭建maven项目(spring + spring MVC + hibernate),希望对于初学者有帮助。
- QHY homework