HDU5044---Tree 树链剖分

大致题意:add1 u v   u到v路径上所有点的权值加上k,add2  u 到v路径上所有边的权值加上k

最后输出所有点的权值,边的权值。。树链剖分预处理然后来个线性O(n)的操作。刚开始用线段树tle了.

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 typedef unsigned long long ull;
  9 typedef long long ll;
 10 const int inf = 0x3f3f3f3f;
 11 const int maxn = 1e5+10;
 12 struct
 13 {
 14     int  to,next;
 15 } e[maxn<<1];
 16 int head[maxn],edge;
 17 void add(int x,int y)
 18 {
 19     e[edge].to = y;
 20     e[edge].next = head[x];
 21     head[x] = edge++;
 22 }
 23
 24 int son[maxn],fa[maxn],siz[maxn],dep[maxn];
 25 void dfs1(int root)
 26 {
 27     siz[root] = 1;
 28     son[root] = 0;
 29     for (int i = head[root]; i > 0; i = e[i].next)
 30     {
 31         if (fa[root] != e[i].to)
 32         {
 33             dep[e[i].to] = dep[root] + 1;
 34             fa[e[i].to] = root;
 35             dfs1(e[i].to);
 36             if (siz[son[root]] < siz[e[i].to])
 37                 son[root] = e[i].to;
 38             siz[root] += siz[e[i].to];
 39         }
 40     }
 41 }
 42 int top[maxn],pos[maxn],fp[maxn],tot;
 43 void dfs2(int root,int f)
 44 {
 45     top[root] = f;
 46     pos[root] = tot++;
 47     fp[pos[root]] = root;
 48     if (son[root]>0)
 49         dfs2(son[root],top[root]);
 50     for (int i = head[root]; i > 0; i = e[i].next)
 51         if (fa[root] != e[i].to && e[i].to != son[root])
 52             dfs2(e[i].to,e[i].to);
 53 }
 54 ll addv[3][maxn<<2];
 55 int k;
 56 void pre_update(int ua,int ub,int cho)
 57 {
 58     int f1 = top[ua];
 59     int f2 = top[ub];
 60     while (f1 != f2)
 61     {
 62         if (dep[f1] < dep[f2])
 63             swap(f1,f2),swap(ua,ub);
 64         addv[cho][pos[f1]] += k;
 65         addv[cho][pos[ua]+1] -= k;
 66         ua = fa[f1];
 67         f1 = top[ua];
 68     }
 69     if (dep[ua] > dep[ub])
 70         swap(ua,ub);
 71     if (cho == 1)
 72         addv[cho][pos[ua]] += k,addv[cho][pos[ub]+1] -= k;
 73     if (cho == 2)
 74         addv[cho][pos[son[ua]]] += k,addv[cho][pos[ub]+1] -= k;
 75 }
 76 int n,m,d[maxn][2],link[maxn];
 77 void init()
 78 {
 79     scanf ("%d%d",&n,&m);
 80     int root = 1;
 81     dep[root] = fa[root] = 0;
 82     edge = tot = 1;
 83     memset(head,0,sizeof(head));
 84     memset(siz,0,sizeof(siz));
 85     memset(addv,0,sizeof(addv));
 86     for (int i = 1; i < n; i++)
 87     {
 88         int u,v;
 89         scanf ("%d%d",&u,&v);
 90         d[i][0] = u;
 91         d[i][1] = v;
 92         add(u,v),add(v,u);
 93     }
 94     dfs1(root);
 95     dfs2(root,root);
 96     for (int i = 1; i < n; i++)
 97     {
 98         if (dep[d[i][0]] < dep[d[i][1]])
 99             swap(d[i][0],d[i][1]);
100         link[d[i][0]] = i;
101     }
102 }
103 ll ans1[maxn],ans2[maxn];
104 int main(void)
105 {
106     //freopen("in.txt","r",stdin);
107     int t;
108     int cas = 1;
109     scanf ("%d",&t);
110     while (t--)
111     {
112         init();
113         for (int i = 0; i < m; i++)
114         {
115             char op[10];
116             int u,v;
117             scanf ("%s%d%d%d",op,&u,&v,&k);
118             pre_update(u,v,op[3]-‘0‘);
119         }
120         for (int i = 1; i <= n; i++)
121         {
122             addv[1][i] += addv[1][i-1];
123             addv[2][i] += addv[2][i-1];
124             ans1[fp[i]] = addv[1][i];
125             ans2[link[fp[i]]] = addv[2][i];
126         }
127         printf("Case #%d:\n",cas++);
128         printf("%I64d",ans1[1]);
129         for (int i = 2; i <= n; i++)
130         {
131             printf(" %I64d",ans1[i]);
132         }
133         printf("\n");
134         if (n>1)
135             printf("%I64d",ans2[1]);
136         for (int i = 2; i < n; i++)
137         {
138             printf(" %I64d",ans2[i]);
139         }
140         printf("\n");
141     }
142     return 0;
143 }

时间: 2024-10-12 03:44:24

HDU5044---Tree 树链剖分的相关文章

hdu5044 Tree 树链剖分,点剖分,边剖分,非递归版

//#pragma warning (disable: 4786) //#pragma comment (linker, "/STACK:16777216") //#pragma comment(linker, "/STACK:60400000,60400000") //HEAD #include <cstdio> #include <ctime> #include <cstdlib> #include <cstring&g

SPOJ375 Query on a tree 树链剖分

SPOJ375  Query on a tree   树链剖分 no tags You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of

SPOJ - QTREE 375 Query on a tree 树链剖分+线段树

操作1:修改第k条边权. 操作2:询问两点间最大边权. 树链剖分,然后线段树维护最大值 #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #inclu

Aizu 2450 Do use segment tree 树链剖分+线段树

Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show.php?pid=39566 Description Given a tree with n (1 ≤ n ≤ 200,000) nodes and a list of q (1 ≤ q ≤ 100,000) queries, process the queries in order and out

spoj 375 Query on a tree (树链剖分)

Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to ti or Q

SPOJ Query on a tree 树链剖分 水题

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of the i-th edge to tior QUERY a b : ask fo

hdu 4912 Paths on the tree(树链剖分+贪心)

题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道,要求尽量选出多的通道,并且两两通道不想交. 解题思路:用树链剖分求LCA,然后根据通道两端节点的LCA深度排序,从深度最大优先选,判断两个节点均没被标 记即为可选通道.每次选完通道,将该通道LCA以下点全部标记. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include

poj 3237 Tree 树链剖分+线段树

Description You are given a tree with N nodes. The tree's nodes are numbered 1 through N and its edges are numbered 1 through N ? 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions

spoj Query on a tree(树链剖分模板题)

375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. We will ask you to perfrom some instructions of the following form: CHANGE i ti : change the cost of

【BZOJ-4353】Play with tree 树链剖分

4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][Discuss] Description 给你一棵包含N个节点的树,设每条边一开始的边权为0,现在有两种操作: 1)给出参数U,V,C,表示把U与V之间的路径上的边权变成C(保证C≥0) 2)给出参数U,V,C,表示把U与V之间的路径上的边权加上C.但是如果U至V之间路径某条边的边权加上C小于0,那