poj 2763 Housewife Wind 边权的树链剖分
2015-09-08 17:33
477 查看
// poj 2763 Housewife Wind 边权的树链剖分 // // 题目意思很清楚,关于边权的树链剖分,首先 // 肯定是先把链剖分好啦,然后就是将边权转化 // 成离根节点较远的点的权值即可.单点更新, // 区间求和,注意,莫要重复计算哟,这题还有需要 // 研究的地方,继续加油吧~~~ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define cls(x,a) memset(x,(a),sizeof(x)) using namespace std; const int maxn = 100000 + 8; int n,q,s; int head[maxn]; int id; int idx[maxn]; int father[maxn]; int siz[maxn]; int son[maxn]; int dep[maxn]; int rk[maxn]; int top[maxn]; int num; struct Node{ int to; int next; Node(){ } Node(int a,int b):to(a),next(b){ } }edges[maxn<<1]; void add_edges(int u,int v){ edges[num] = Node(v,head[u]); head[u] = num++; } struct edge{ int u; int v; int w; edge(){ } edge(int u,int v,int w):u(u),v(v),w(w){ } }e[maxn]; void dfs(int u,int fa,int d){ siz[u] = 1; dep[u] = d; son[u] = 0; father[u] = fa; for (int i = head[u];i != -1; i = edges[i].next){ int v = edges[i].to; if (v == fa) continue; dfs(v,u,d+1); siz[u] += siz[v]; if (siz[son[u]] < siz[v]){ son[u] = v; } } } void dfs(int u,int tp){ top[u] = tp; idx[u] = id++; rk[idx[u]] = u; if (son[u]) dfs(son[u],tp); for (int i = head[u];i != -1;i = edges[i].next){ int v = edges[i].to; if (v == father[u] || v == son[u]) continue; dfs(v,v); } } #define lson(x) (x<<1) #define rson(x) (x<<1|1) int seg[maxn<<2]; int val[maxn]; void push_up(int ro){ seg[ro] = seg[lson(ro)] + seg[rson(ro)]; } void build(int ro,int L,int R){ if (L == R){ seg[ro] = val[L]; return ; } int M = (L+R)>>1; build(lson(ro),L,M); build(rson(ro),M+1,R); push_up(ro); } int ql,qr,delta; void update(int ro,int L,int R){ if (L == R){ seg[ro] = delta; return ; } int M = (L + R) >> 1; if (ql <= M) update(lson(ro),L,M); else update(rson(ro),M+1,R); push_up(ro); } int query(int ro,int L,int R){ if (ql<= L && R<= qr){ return seg[ro]; } int M = (L + R) >> 1; int ans = 0; if (ql <= M) ans += query(lson(ro),L,M); if (M < qr) ans += query(rson(ro),M+1,R); return ans; } int get(int u,int v){ int p = top[u],q = top[v]; int ans = 0; while(p != q){ if (dep[p] < dep[q]){ swap(u,v); swap(p,q); } ql = idx[p]; qr = idx[u]; ans += query(1,1,n); u = father[p]; p = top[u]; } if (u == v) return ans; if (dep[u] > dep[v]){ swap(u,v); } ql = idx[son[u]]; qr = idx[v]; ans += query(1,1,n); return ans; } void input(){ cls(head,-1); num = 0; id = 1; for (int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); e[i] = edge(u,v,w); add_edges(u,v); add_edges(v,u); } dfs(1,0,0); dfs(1,1); for (int i=1;i<n;i++){ if (dep[e[i].u] < dep[e[i].v]) swap(e[i].u,e[i].v); val[idx[e[i].u]] = e[i].w; } build(1,1,n); for (int i=1;i<=q;i++){ int k,u,v; scanf("%d",&k); if (k==0){ scanf("%d",&u); printf("%d\n",get(s,u)); s = u; }else { scanf("%d%d",&u,&v); ql = idx[e[u].u]; delta = v; update(1,1,n); } } } int main(){ //freopen("1.txt","r",stdin); while(scanf("%d%d%d",&n,&q,&s)!=EOF){ input(); } }
相关文章推荐
- javascript 中的 delete
- 18. CSS 内边距
- js创建对象
- 深入解析HTML5中的Blob对象的使用
- node-xlsx使用教程
- 前端获取元素定位位置的法宝
- jquery控制按钮的禁用与启用
- i18next-页面层语言国际化js框架介绍
- 剑指offer 算法(树的两个节点的最低祖先)
- Firebase, Netty, Feed Push
- react-native试玩(33)-状态栏API
- fastjson生成和解析json数据
- Grunt 单独对css压缩并生成min.css文件
- CSS 最核心的几个概念
- easy ui jquery 添加时样式出现问题
- javascript中加法操作符与减法操作符在字符串与数字相加时的区别
- jquery+ajax简单例子及jquery事件
- JavaScript总结(一)
- js中变量的作用域
- HtmlUnit解析document时js不能拿到body对象问题解决