首页 > 代码库 > HDU 5044 TREE
HDU 5044 TREE
题意:一棵树上两种操作,操作1,改变u到v的每一点的值增加k,操作2,改变u到v每一条边值增加k。最后结束时问,每一点和每一条边的值。
初始时,点和边的值都为0.
分析:
很显然要用树链剖分,将点和边分别划分成连续一段的编号,然后就是维护一段一段的值了,给它增加一个值,由于题目只需要输出最后结果,那么可以用树桩数组维护。
以边为例,对于l~r的每个值增加k,利用树桩数组v[i]表示第i个值与前一个值的差值,那么第k条边的值就是sum{v[i]| 1 <= i <= k},更新时则只要给v[l]加k,给v[r+1]加(- k), 这个都可以累加下来,最后依次对每个v[i]更新,然后求出结果就行了。
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <map> 5 #include <cstring> 6 #include <set> 7 #include <bitset> 8 #include <cstdio> 9 #include <cmath> 10 #define esp 1e-8 11 #pragma comment(linker, "/STACK:102400000,102400000") 12 #define in freopen("F:\\rootial\\data\\data.txt", "r", stdin); 13 #define IN freopen("solve_in.txt", "r", stdin); 14 #define out freopen("out.txt", "w", stdout); 15 #define pf(x) ((x)*(x)) 16 #define lowbit(x) ((x)&(-(x))) 17 #define bug(x) printf("Line %d: >>>>>>\n", (x)); 18 #define lson l, m, rt<<1 19 #define rson m+1, r, rt<<1|1 20 #define pb push_back 21 #define mp make_pair 22 #define pi acos(-1.0) 23 #define pf(x) ((x)*(x)) 24 25 using namespace std; 26 typedef long long LL; 27 typedef pair<int, int> PII; 28 typedef map<LL, LL> MPS; 29 typedef MPS::iterator IT; 30 31 const int maxn = (int)1e5 + 100; 32 LL vv[2][maxn]; 33 int n, m; 34 int top[maxn], num[maxn], tnum[maxn], ID[maxn], son[maxn], sz[maxn], fa[maxn], dep[maxn], tmp[maxn]; 35 int cnt; 36 37 struct Edge 38 { 39 int v, id; 40 Edge() {} 41 Edge(int v, int id):v(v), id(id) {} 42 } edge[maxn*2]; 43 int fi[maxn], nxt[maxn*2]; 44 LL q[2][maxn]; 45 46 void update(int x, LL v[], LL val) 47 { 48 while(x <= n) 49 { 50 v[x] +=val; 51 x += lowbit(x); 52 } 53 } 54 void update(int l, int r, LL val, LL v[]) 55 { 56 update(l, v, val); 57 update(r+1, v, -val); 58 } 59 60 void query(int x, LL &res1, LL &res2) 61 { 62 res1 = 0, res2 = 0; 63 while(x > 0) 64 { 65 res1 += vv[0][x]; 66 res2 += vv[1][x]; 67 x -= lowbit(x); 68 } 69 } 70 void dfs1(int u, int f) 71 { 72 fa[u] = f; 73 dep[u] = dep[f] + 1; 74 sz[u] = 1; 75 for(int i = fi[u]; i; i = nxt[i]) 76 { 77 int v = edge[i].v; 78 int id = edge[i].id; 79 if(v == f) 80 continue; 81 tmp[v] = id; 82 dfs1(v, u); 83 sz[u] += sz[v]; 84 if(sz[son[u]] < sz[v]) 85 son[u] = v; 86 } 87 } 88 void dfs2(int u, int f) 89 { 90 if(son[u]) 91 { 92 num[son[u]] = ++cnt; 93 top[son[u]] = top[u]; 94 ID[tmp[son[u]]] = cnt; 95 dfs2(son[u], u); 96 } 97 for(int i = fi[u]; i; i = nxt[i]) 98 { 99 int v = edge[i].v;100 int id = edge[i].id;101 if(v == f || v == son[u]) continue;102 top[v] = v;103 num[v] = ++cnt;104 ID[tmp[v]] = cnt;105 dfs2(v, u);106 }107 }108 void init()109 {110 for(int i = 0; i <= n; i++)111 {112 vv[0][i] = vv[1][i] = 0;113 son[i] = 0;114 sz[i] = 0;115 fa[i] = 0;116 cnt = 0;117 fi[i] = 0;118 nxt[i<<1] = nxt[i<<1|1] = 0;119 q[0][i] = q[1][i] = 0;120 }121 }122 void add(int u, int v, int x)123 {124 edge[++cnt] = Edge(v, x);125 nxt[cnt] = fi[u];126 fi[u] = cnt;127 edge[++cnt] = Edge(u, x);128 nxt[cnt] = fi[v];129 fi[v] = cnt;130 }131 void input()132 {133 scanf("%d%d", &n, &m);134 init();135 for(int i = 1; i < n; i++)136 {137 int u, v;138 scanf("%d%d", &u, &v);139 add(u, v, i);140 }141 cnt = 0;142 }143 inline bool isdigit(char ch)144 {145 return ch >= ‘0‘ && ch <= ‘9‘;146 }147 const LL B = (int)1e5 + 10;148 149 void update(int u, int v, int k) //dian150 {151 while(top[u] != top[v])152 {153 if(dep[top[u]] < dep[top[v]]) swap(u, v);154 q[0][num[top[u]]] += k;155 q[0][num[u]+1] -= k;156 u = fa[top[u]];157 }158 if(dep[u] < dep[v]) swap(u, v);159 q[0][num[v]] += k;160 q[0][num[u]+1] -= k;161 }162 void update1(int u, int v, int k) //bian163 {164 while(top[u] != top[v])165 {166 if(dep[top[u]] < dep[top[v]]) swap(u, v);167 if(u != top[u])168 {169 q[1][num[son[top[u]]]] += k;170 q[1][num[u]+1] -= k;171 }172 u = top[u];173 q[1][num[u]] += k;174 q[1][num[u]+1] -= k;;175 u = fa[u];176 }177 if(dep[u] < dep[v]) swap(u, v);178 if(u != v)179 {180 q[1][num[son[v]]] += k;181 q[1][num[u]+1] -= k;182 }183 }184 LL ans[maxn];185 186 void solve()187 {188 dfs1(1, 0);189 top[1] = 1;190 num[1] = ++cnt;191 dfs2(1, 0);192 for(int i = 0; i < m; i++)193 {194 char s[20];195 int u, v, k;196 scanf("%s%d%d%d", s, &u, &v, &k);197 if(strcmp(s, "ADD1") == 0)198 {199 update(u, v, k);200 }201 else202 {203 update1(u, v, k);204 }205 }206 for(int k = 0; k < 2; k++){207 for(int i = 1; i <= n; i++)208 update(i, vv[k], q[k][i]);209 }210 211 for(int i = 1; i <= n; i++)212 {213 LL res1, res2;214 query(num[i], res1, res2);215 ans[num[i]] = res2;216 printf("%I64d%c", res1, i == n ? ‘\n‘ : ‘ ‘);217 }218 for(int i = 1; i <= n-1; i++)219 {220 LL res = ans[ID[i]];221 printf("%I64d%c", res, i == n-1 ? ‘\n‘ : ‘ ‘);222 }223 if(n == 1)224 puts("");225 }226 int main()227 {228 229 int T;230 for(int t = scanf("%d", &T); t <= T; t++)231 {232 printf("Case #%d:\n", t);233 input();234 solve();235 }236 return 0;237 }
HDU 5044 TREE
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。