HDU5044--Tree(树链剖分)
来源:互联网 发布:淘宝宝贝编辑教程 编辑:程序博客网 时间:2024/05/22 03:40
Problem Description
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.
Input
The first line of the input is T (1 ≤ T ≤ 20), which stands for the number of test cases you need to solve.
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, -105 ≤ k ≤ 105)
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, -105 ≤ k ≤ 105)
Output
For each test case, print a line “Case #t:”(without quotes, t means the index of the test case) at the beginning.
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.
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.
Sample Input
24 21 22 32 4ADD1 1 4 1ADD2 3 4 24 21 22 31 4ADD1 1 4 5ADD2 3 2 4
Sample Output
Case #1:1 1 0 10 2 2Case #2:5 0 0 50 4 0
思路:树链剖分。。常规做法要TLE、、、
这里先把链拆成线段,然后线扫描一遍、
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <iomanip>#include <cassert>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)#define travel(e, u) for(int e = u, v = vv[u]; e; e = nxt[e], v = vv[e])#define bit(n) (1LL<<(n))typedef long long LL;typedef unsigned long long ULL;void work();int main(){// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout); work();}void scanf(int & x, char c = 0){ while((c = getchar()) < '0' || c > '9'); x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = x * 10 + (c - '0');}/*****************************************华丽分割线**********************************************/#define maxn 200800#define N 100080#define lson id<<1,l,mid#define rson id<<1|1,mid+1,rint first[N],nxt[maxn],vv[maxn];int fa[N],Pos[N],Size[N],Son[N],fPos[N];int dep[N],Top[N];char ope[10];LL Ans1[N],Ans2[N];int e,pos;int firstadd[N],Nxt[10*maxn],Vv[10*maxn];int firstadd2[N],Nxt2[10*maxn],Vv2[10*maxn];int E,E2;void scanf_f(int & a) { bool ok = 0; a = 0; char c; while((c = getchar()) < '0' || c > '9') { if(c == '-') ok = 1; } a = c - '0'; while((c = getchar()) >= '0' && c <= '9') a = a*10 + c - '0'; if(ok) a = -a;} void init(int n){ e = pos = E = E2 = 0; memset(first,-1,sizeof(first)); memset(firstadd,-1,sizeof(firstadd)); memset(firstadd2,-1,sizeof(firstadd2)); memset(Son,-1,sizeof(Son));}void addedge(int u,int v){ vv[e] = v; nxt[e] = first[u]; first[u] = e++; vv[e] = u; nxt[e] = first[v]; first[v] = e++;}void AddEdge(int u,int v){ Vv[E] = v; Nxt[E] = firstadd[u]; firstadd[u] = E++;}void AddEdge2(int u,int v){ Vv2[E2] = v; Nxt2[E2] = firstadd2[u]; firstadd2[u] = E2++;}void dfs(int u,int pre){ dep[u] = dep[pre] + 1; Size[u] = 1; for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(v == pre) continue; fa[v] = u; dfs(v,u); Size[u] += Size[v]; if(Son[u] == -1 || Size[v] > Size[Son[u]]) Son[u] = v; }}void dfs2(int u,int t){ Pos[u] = ++pos; fPos[pos] = u; Top[u] = t; if(Son[u] != -1) dfs2(Son[u],t); for(int i = first[u];i != -1;i = nxt[i]) { int v = vv[i]; if(v != fa[u] && v != Son[u]) dfs2(v,v); }}void gao(int u,int v,int add){ int f1 = Top[u],f2 = Top[v]; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(u,v); swap(f1,f2); } AddEdge(Pos[f1],add); AddEdge(Pos[u]+1,-add); u = fa[f1]; f1 = Top[u]; } if(dep[u] > dep[v]) swap(u,v); AddEdge(Pos[u],add); AddEdge(Pos[v]+1,-add);}void gao1(int u,int v,int add){ int f1 = Top[u],f2 = Top[v]; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(u,v); swap(f1,f2); } if(f1 == u) { AddEdge2(Pos[f1],add); AddEdge2(Pos[u]+1,-add); } else { AddEdge2(Pos[f1],add); AddEdge2(Pos[u]+1,-add); } u = fa[f1]; f1 = Top[u]; } if(dep[u] > dep[v]) swap(u,v); AddEdge2(Pos[Son[u]],add); AddEdge2(Pos[v]+1,-add);}struct Edge{ int u,v;}edge[N];void work(){ int t,cas = 0; scanf("%d",&t); while(t--) { int n,m; scanf_f(n); scanf_f(m); init(n); for(int i = 1;i < n;i++) { int u,v; scanf_f(u); scanf_f(v); addedge(u,v); edge[i].u = u,edge[i].v = v; } dep[1] = 0; dfs(1,1); dfs2(1,1); int u,v,k; for(int i = 1;i <= m;i++) { scanf("%s",ope); if(ope[3] == '1') { scanf_f(u); scanf_f(v); scanf_f(k); gao(u,v,k); } else { scanf_f(u); scanf_f(v); scanf_f(k); gao1(u,v,k); } } printf("Case #%d:\n",++cas); LL ans1 = 0,ans2 = 0; for(int i = 1;i <= n;i++) { for(int j = firstadd[i];j != -1;j = Nxt[j]) ans1 += Vv[j]; for(int j = firstadd2[i];j != -1;j = Nxt2[j]) ans2 += Vv2[j]; Ans1[fPos[i]] = ans1; Ans2[fPos[i]] = ans2; } for(int i = 1;i <= n;i++) { printf("%I64d",Ans1[i]); if(i == n) puts(""); else printf(" "); } for(int i= 1;i < n;i++) { u = edge[i].u,v = edge[i].v; if(dep[u] > dep[v]) swap(u,v); printf("%I64d",Ans2[v]); if(i != n-1) printf(" "); } puts(""); }}
0 0
- HDU5044--Tree(树链剖分)
- HDU5044 Tree(树链剖分)
- hdu5044 Tree(树链剖分+差分)
- hdu5044(神姿势+树链剖分)
- 树链剖分+离散+扫描(HDU5044)
- hdu5044 Tree 树链剖分,点剖分,边剖分,非递归版
- hdu3966 or hdu5044 树链剖分
- 2014上海网络预选赛1003(树链剖分)HDU5044
- hdu5044(树链剖分+标记法实现区间更新)
- HDU5044 2014上海网络赛1003 tree
- hdu5044 Tree 上海网络赛1003 LCA+输入输出外挂
- hdu5044(二分)
- HDU5044【LCA+差分】
- 【POJ3237】Tree(树链剖分)
- SPOJ-tree:Query on a tree (树链剖分)
- poj 3237 Tree(树链剖分)
- HDU 5044 - Tree (树链剖分)
- POJ 3723 Tree(树链剖分)
- Java include指令 使用示例
- js中eval的一个使用示例
- RAC监听日志与CRS日志 及常用命令
- hdu 5045 Contest (状压DP)
- android网络编程之post提交数据
- HDU5044--Tree(树链剖分)
- CalTech machiine learning, video 10 note(Neural Network)
- Hive之数据查询
- android网络编程之get
- 如何删除C/C++源代码中的注释
- 杭电acm2026首字母变大写
- BugFree安装后/site/login不能访问出现404问题的解决方法
- Android中SharedPreference多进程数据共享出错
- URAL 1644 A Whole Lot of Walnuts (水