CSU 1663 2015湖南多校对抗赛06.22
2015-06-23 23:59
501 查看
题目链接
给定一棵50000个点的树,有以下三种操作:
1.将一条边权修改为X
2.将A到B路径上的所有边权乘以C
3.询问A到B路径上的边权和
思路
看到点权50000以及树上路径操作,直接上树链剖分
一些细节:
1.线段树共俩个标记区间和Sum,以及区间倍数Dt
2.Dt初始为1,C可以为负数,所以用Dt != 1判断是否下放
Code
给定一棵50000个点的树,有以下三种操作:
1.将一条边权修改为X
2.将A到B路径上的所有边权乘以C
3.询问A到B路径上的边权和
思路
看到点权50000以及树上路径操作,直接上树链剖分
一些细节:
1.线段树共俩个标记区间和Sum,以及区间倍数Dt
2.Dt初始为1,C可以为负数,所以用Dt != 1判断是否下放
Code
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algorithm> #include <vector> typedef long long ll; using namespace std; #define foru(i, a, b) for(ll i=(a); i<=(b); i++) #define ford(i, a, b) for(ll i=(a); i>=(b); i--) #define clr(a, b) memset(a, b, sizeof(a)) const int N = 50010; struct Edge{ int a, b; ll c; }E ; int n, tot; int adj , aim[2*N], nxt[2*N]; void add(int a, int b){ tot ++; aim[tot] = b; nxt[tot] = adj[a]; adj[a] = tot; } void init(){ tot = 0; clr(adj, 0); scanf("%d", &n); foru(i, 1, n-1){ scanf("%d %d %lld", &E[i].a, &E[i].b, &E[i].c); add(E[i].a, E[i].b); add(E[i].b, E[i].a); } } int num, l, r; int fa , son , siz , dep , idx , top ; int L[4*N], R[4*N], mid[4*N]; ll Sum[4*N], dt[4*N], ans; void dfs(int x, int pre, int d){ fa[x] = pre; siz[x] = 1; dep[x] = d; int k = adj[x]; while (k){ int tx = aim[k]; if (tx != pre){ dfs(tx, x, d+1); siz[x] += siz[tx]; if (siz[tx] > siz[son[x]]) son[x] = tx; } k = nxt[k]; } } void get_tree(int x, int pre){ idx[x] = ++ num; top[x] = pre; if (son[x]) get_tree(son[x], top[x]); int k = adj[x]; while (k){ int tx = aim[k]; if (tx != son[x] && tx != fa[x]) get_tree(tx, tx); k = nxt[k]; } } void build(int l, int r, int i){ L[i] = l; R[i] = r; dt[i] = 1; if (l == r) return; mid[i] = (l + r) >> 1; build(l, mid[i], i<<1); build(mid[i]+1, r, (i<<1)+1); } void down(int i){ Sum[i << 1] *= dt[i]; Sum[(i<<1)+1] *= dt[i]; dt[i<< 1] *= dt[i]; dt[(i<<1)+1] *= dt[i]; dt[i] = 1; } void modify(int k, ll x, int i){ if (L[i] == R[i]) { Sum[i] = x; return; } if (dt[i] != 1) down(i); if (k <= mid[i]) modify(k, x, i<<1); else modify(k, x, (i<<1)+1); Sum[i] = Sum[i<<1] + Sum[(i<<1)+1]; } int root; void prepare(){ num = 0; root = (n + 1) >> 1; clr(son, 0); dfs(root, root, 1); get_tree(root, root); build(1, num, 1); foru(i, 1, n-1){ if (dep[E[i].a] > dep[E[i].b]) swap(E[i].a, E[i].b); modify(idx[E[i].b], E[i].c, 1); } } void get(int a, int b, int i){ if (a <= L[i] && R[i] <= b){ ans = ans + Sum[i]; return; } if (dt[i] != 1) down(i); if (a <= mid[i]) get(a, b, i<<1); if (b > mid[i]) get(a, b, (i<<1)+1); } ll query(int x, int y){ int fx = top[x], fy = top[y]; ans = 0; while (fx != fy){ if (dep[fx] < dep[fy]){ swap(x, y); swap(fx, fy); } get(idx[fx], idx[x], 1); x = fa[fx]; fx = top[x]; } if (x == y) return ans; if (dep[x] > dep[y]) swap(x, y); get(idx[son[x]], idx[y], 1); return ans; } void change(int a, int b, ll c, int i){ if (a <= L[i] && R[i] <= b){ Sum[i] *= c; dt[i] *= c; return; } if (dt[i] != 1) down(i); if (a <= mid[i]) change(a, b, c, i<<1); if (b > mid[i]) change(a, b, c, (i<<1)+1); Sum[i] = Sum[i<<1] + Sum[(i<<1)+1]; } void updata(int x, int y, ll c){ int fx = top[x], fy = top[y]; while (fx != fy){ if (dep[fx] < dep[fy]){ swap(x, y); swap(fx, fy); } change(idx[fx], idx[x], c, 1); x = fa[fx]; fx = top[x]; } if (x == y) return; if (dep[x] > dep[y]) swap(x, y); change(idx[son[x]], idx[y], c, 1); } void solve(){ char cmd[10]; while (1){ int i, a, b; ll c; scanf("%s", cmd); if (cmd[0] == 'E') return; if (cmd[0] == 'C'){ scanf("%d %lld", &i, &c); modify(idx[E[i].b], c, 1); continue; } if (cmd[0] == 'M'){ scanf("%d%d%lld", &a, &b, &c); updata(a, b, c); continue; } scanf("%d%d", &a, &b); printf("%lld\n", query(a, b)); } } int main(){ freopen("G.txt", "r", stdin); int T; scanf("%d", &T); while (T--){ init(); prepare(); solve(); } return 0; }
相关文章推荐
- Google Chrome浏览器调试功能介绍
- 02-如何实例化模型
- 资源--timer的使用
- MacBookPro如何安装双系统
- 共享思源黑体ttf版,还有Mac下7z压缩
- java中间件学习6-java网络通信实现选择
- 01-编写CMS注意事项
- LeetCode——House Robber
- 学习《Python核心编程》做一下知识点提要,方便复习(二)
- Web开发模板
- Java集合框架总结
- 获取自然日之差
- Nearest Numbers
- Java基础:字符串
- ThinkPHP 利用.htaccess文件的 Rewrite 规则隐藏URL中的 index.php
- ThinkPhp学习13
- 谈谈Ext JS的组件——容器与布局
- 谈谈Ext JS的组件――容器与布局
- leetcode 226 Invert Binary Tree 翻转二叉树
- leetcode 226 Invert Binary Tree 翻转二叉树