这道题可以树链剖分做。但是最近在给学弟搞数据结构复习了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. jQuery 初识 筛选器 属性选择器

    ---------------------------大事使我们惊讶,小事使我们沮丧,久而久之,我们对这二者都会习以为常. 一 jQuery是什么? [1]   jQuery由美国人John Resi ...

  2. 广播频道-BroadcastChannel

    BroadcastChannel,就字面意思来言,叫做“广播频道”,官方文档说,该API是用于同源不同页面之间完成通信的功能. 1. 概况 它与window.postMessage的区别就是,Broa ...

  3. 美团2016秋招笔试B

    1.下述解决死锁的方法中,属于死锁预防策略的是? 资源有序分配法  银行家算法:避免死锁 资源有序分配法:预防死锁 资源分配图化简法:检测死锁 撤销进程法:解决死锁   2. 什么是死锁? 如果一个进 ...

  4. 用PhoneGap创建第一个项目

    1.在eclipse中新建Android Project2.在项目的目录下,建两个文件夹:/libs/assets/www3.进入将刚刚下载并解压的PhoneGap包里Anroid目录,我们需要的资源 ...

  5. 史上最全 原生javascript的知识总结,适合新手及查资料用!

    适合右键另存为图片保存,再放大看!

  6. net core 小坑杂记之配置文件读取(不定期更新)

    其实很早就想写了,原想等积累差不多了再写的,但是发现遇到一个当时记下效果会比较好,所以就不定期更新这个系列了,后面获取会整个整理一下. 此篇记载net core入门时踩的一些坑,网上教程太少了,也不规 ...

  7. httpd.conf简单配置

    本文介绍apache中httpd.conf的配置.该配置也可解决打开php文件却变成下载的尴尬情况 1 修改网站根目录查找DocumentRoot有这么一行DocumentRoot "C:/ ...

  8. JavaWeb连接SQLServer数据库并完成一个登录界面及其功能设计。

    一.JDBC连接SQLserver数据库的步骤: 1.下载SQLserver的JDBC驱动文件——Microsoft JDBC Driver 4.0 for SQL Server 2.例如下载得到的文 ...

  9. SOAP UI-----测webservice接口

    webservice的请求报文和返回报文都是xml格式的. 使用soapui.storm对webservice接口进行测试,postman无法测. http://www.webxml.com.cn/W ...

  10. 【问题解决方案】editplus中批量将ANSI转换为utf-8

    来自一个用editplus写java程序但是上传到GitHub里中文乱码的故事 大致步骤: editplus全部打开之后(打开为何种编码不重要): (全部打开是指在左下方的文件列表选中-->右击 ...