这道题可以树链剖分做。但是最近在给学弟搞数据结构复习了LCA树状数组RMQ

然后就搞了一发LCA+树状数组维护。

dis数组维护当前点到根节点的权值和。则dis(u,v) = dis[u]+dis[v]-2*dis[lca(u,v)]

修改的时候,单点修改影响了该点所有儿子的dis,刚好可以用dfs序定位所有儿子,用树状数组改段求点很方便。

http://blog.csdn.net/q573290534/article/details/6664454 树状数组的三种求和(改点求段,改段求点,改段求段)

http://blog.csdn.net/qwe2434127/article/details/49819975 dfs序题目类型

http://www.cnblogs.com/longdouhzt/archive/2011/10/16/2214034.html LCA题目小节

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = 2e5+; int N,Q,S;
//vector <int> G[maxn]; struct edge{
int to,next,w;
}e[*maxn]; int head[*maxn],tot;
void add_edge(int u,int v,int w)
{
e[tot].to = v;
e[tot].w = w;
e[tot].next = head[u];
head[u] = tot++; e[tot].to = u;
e[tot].w = w;
e[tot].next = head[v];
head[v] = tot++;
} int in[maxn],out[maxn],P[*maxn],fa[maxn][],dep[maxn],dis[maxn],cnt;
void dfs(int u,int _fa,int _dep,int _dis)
{
in[u] = ++cnt;
P[cnt] = u;
fa[u][] = _fa;
dis[u] = _dis;
dep[u] = _dep;
for(int i=head[u];~i;i=e[i].next)
{
int v = e[i].to;
if(v == _fa) continue;
dfs(v,u,_dep+,_dis+e[i].w);
}
out[u] = ++cnt;
}
void debug()
{
printf("in:\t");for(int i=;i<=N;i++) printf("%d ",in[i]);puts("");
printf("out:\t");for(int i=;i<=N;i++) printf("%d ",out[i]);puts("");
printf("p:\t");for(int i=;i<=cnt;i++) printf("%d ",P[i]);puts("");
printf("dis:\t");for(int i=;i<=N;i++) printf("%d ",dis[i]);puts("");
printf("dep:\t");for(int i=;i<=N;i++) printf("%d ",dep[i]);puts("");
printf("edge:");for(int i=;i<tot;i++) printf("\tto:%d w:%d\n",e[i].to,e[i].w);
} int initLCA()
{
int m = (int)log(N)/log()+;
for(int k=;k<m;k++)
{
for(int v=;v<=N;v++)
{
if(fa[v][k] < ) {fa[v][k+] = -;continue;}
else fa[v][k+] = fa[fa[v][k]][k];
}
}
} int LCA(int u,int v)
{
int m = (int)log(N)/log()+;
if(dep[v] > dep[u]) swap(u,v);
for(int k=;k<m;k++)
{
if((dep[u]-dep[v])>>k & )
u = fa[u][k];
}
if(u == v) return u;
for(int k=m-;k>=;k--)
{
if(fa[u][k] != fa[v][k])
{
u = fa[u][k];
v = fa[v][k];
}
}
return fa[u][];
} int c[*maxn];
int lowbit(int x) {return x&-x;} void init()
{
memset(head,-,sizeof head);
memset(fa,-,sizeof fa);
memset(c,,sizeof c);
memset(in,,sizeof in);
memset(out,,sizeof out);
tot = ;
cnt = ;
} void add(int x,int d)
{
while(x)
{
c[x] += d;
x -= lowbit(x);
}
}
void add_seg(int l,int r,int d)
{
add(r,d);
add(l-,-d);
}
int sum(int x)
{
int res = ;
//printf("u:%d ",P[x]);
while(x <= cnt)
{
res += c[x];
x += lowbit(x);
}
//printf("res:%d\n",res);
return res;
}
int dist(int x)
{
if(x == -) return ;
return sum(in[x]) + dis[x];
}
int main()
{
//freopen("input.txt","r",stdin);
while(~scanf("%d%d%d",&N,&Q,&S))
{
init();
for(int i=,u,v,w;i<N-;i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}
dfs(,-,,);
//debug();
initLCA();
for(int i=;i<tot;i+=)
{
if(dep[e[i].to] < dep[e[i+].to]) swap(e[i].to,e[i+].to);
}
int op;
for(int i=,a,b,c;i<Q;i++)
{
scanf("%d",&op);
if(op == )
{
scanf("%d",&a);
int lca = LCA(S,a);
//printf("lca:%d\n",lca); printf("%d\n",dist(S)+dist(a)-*(dist(lca)));
S = a;
}else
{
scanf("%d%d",&a,&b);
a--;
int u = e[a*].to;
int dw = b - (dist(u) - dist(fa[u][]));
//printf("dw:%d u:%d\n",dw,u);
add_seg(in[u],out[u],dw);
}
}
}
}

POJ2763-Housewife Wind-树上单点修改区间求和的更多相关文章

  1. 【DFS序+单点修改区间求和】POJ 3321 Apple Tree

    poj.org/problem?id=3321 [题意] 给一棵n个节点的树,每个节点开始有一个苹果,m次操作 1.将某个结点的苹果数异或 1 2.查询一棵子树内的苹果数 #include<io ...

  2. Lightoj 1348 Aladdin and the Return Journey (树链剖分)(线段树单点修改区间求和)

    Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't wa ...

  3. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  4. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  5. LightOJ 1112 Curious Robin Hood (单点更新+区间求和)

    http://lightoj.com/volume_showproblem.php?problem=1112 题目大意: 1 i        将第i个数值输出,并将第i个值清0 2 i v     ...

  6. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  7. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  8. HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和)

    HDOJ(HDU).1166 敌兵布阵 (ST 单点更新 区间求和) 点我挑战题目 题意分析 根据数据范围和询问次数的规模,应该不难看出是个数据结构题目,题目比较裸.题中包括以下命令: 1.Add(i ...

  9. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. python--Numpy and Pandas 笔记01

    博客地址:http://www.cnblogs.com/yudanqu/ 1 import numpy as np import pandas as pd from pandas import Ser ...

  2. 常见的web攻击手段总结

    xxs攻击(跨站脚本攻击) 攻击者在网页中嵌入恶意脚本程序,当用户打开该网页时脚本程序便在浏览器上执行,盗取客户端的cookie.用户名密码.下载执行病毒木马程 序 解决: 我们可以对用户输入的数据进 ...

  3. CentOS 6 升级 curl

    zabbix 发邮件报 Support for SMTP authentication was not compiled in 其实出现这种问题的原因是我们机器上的 libcurl 版本太低所致.在z ...

  4. 01-JavaScript介绍

    JavaScript价绍 1.引言 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) ...

  5. latex 图片标题居中

    1.有一个全局图片标题居中的方法: \usepackage[justification=centering]{caption} 2.如果排版时有的图标题想左对齐,有的想居中,前一个方法就不好了,这里可 ...

  6. HashSet中存放不重复元素

    一.自定义对象存放在hashSet中,保证元素不重复.重写hashCode()和equals()方法 public class Student{ private String name; privat ...

  7. node笔记

    基础入门可参考: <一起学 Node.js>—— https://github.com/nswbmw/N-blog 核心模块使用前需要引入   let fs=require('fs'); ...

  8. linux命令:拷贝命令家族(cp、scp、rsync)

    Linux命令中:rsync和cp之间的区别 - 小 楼 一 夜 听 春 雨 - 博客园https://www.cnblogs.com/kex1n/p/7008178.html cp,scp,rsyn ...

  9. 父级div宽度100%,子级一个div宽度固定,另一个宽度自适应

    <!DOCTYPE html> <html> <head> <title>布局测试</title> <style type=" ...

  10. telnet总结

    telnet是经常使用的客户端链接工具,总结一下常用的telnet的使用方法 1) 连接 telnet //链接swoole 2)退出当前连接 ctrl + ] 回车 3)查看常用的一些命令 ? 回车 ...