BZOJ3730 震波


Description

在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]。

不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。

接下来你需要在线处理M次操作:

0 x k 表示发生了一次地震,震中城市为x,影响范围为k,所有与x距离不超过k的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。

1 x y 表示第x个城市的价值变成了y。

为了体现程序的在线性,操作中的x、y、k都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为0。

Input

第一行包含两个正整数N和M。

第二行包含N个正整数,第i个数表示value[i]

接下来N-1行,每行包含两个正整数u、v,表示u和v之间有一条无向边。

接下来M行,每行包含三个数,表示M次操作。

Output

包含若干行,对于每个询问输出一行一个正整数表示答案。

Sample Input

8 1

1 10 100 1000 10000 100000 1000000 10000000

1 2

1 3

2 4

2 5

3 6

3 7

3 8

0 3 1

Sample Output

11100101

HINT

1<=N,M<=100000

1<=u,v,x<=N

1<=value[i],y<=10000

0<=k<=N-1


动态点分治

噗噗噗恶习死了

首先我们是肯定需要求出两点间的路径的,然后就可以上倍增LCA的板子

然后开始考虑怎么维护答案

如果不考虑修改

每次询问的答案可以用怎样的形式来统计呢?

因为我们维护一个点的字树信息很方便,所以就可以先用树状数组维护一下一个子树里的信息,以距离为下标,点权直接单点加上就行了

现在考虑怎么统计子树外边的贡献,首先我们可以跳到点分树上的prt节点上,然后求出prt到当前节点u的距离len,用查询距离k减去len,查询在prt的子树里边有多少距离小于等于k-len的点就可以了,但是我们发现在u的子树内的一部分节点会被重复计算,所以我们需要另开一个树状数组来维护重复的贡献,在这个树状数组里边只记录在u的子树中的额外贡献

现在考虑吧修改加上,我们从修改节点x这个点开始,不停向prt跳,然后我们这里可以把每一个原来是val[x]的贡献换成y的贡献,简而言之就是加上y-val[x],然后跟查询差不多,只不过反向维护一下就好了

然后细节一大堆,主要就是跳prt维护的细节


#include<bits/stdc++.h>
using namespace std;
#define N 500010
inline int read(){
int ans=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')w=-1,c=getchar();
while(isdigit(c))ans=(ans<<1)+(ans<<3)+c-'0',c=getchar();
return ans*w;
}
int n,m,lastans=0,val[N],Log[N];
struct Edge{
int v,next;
Edge(){}
Edge(int v,int next):v(v),next(next){}
}E[N<<1];
int head[N],tot=0;
void add(int u,int v){
E[++tot]=Edge(v,head[u]);
head[u]=tot;
}
int dep[N]={0},Fa[N][21];
void getFa(int u,int fa){
Fa[u][0]=fa;
dep[u]=dep[fa]+1;
for(int i=1;i<=20;i++)Fa[u][i]=Fa[Fa[u][i-1]][i-1];
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v==fa)continue;
getFa(v,u);
}
}
int Lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int t=dep[x]-dep[y],k=Log[n]+1;
for(int i=0;i<=k;i++)
if(t&(1<<i))x=Fa[x][i];
if(x==y)return x;
while(Fa[x][0]!=Fa[y][0]){
if(Fa[x][k]!=Fa[y][k]){
x=Fa[x][k];
y=Fa[y][k];
}
k--;
}
return Fa[x][0];
}
int getdis(int x,int y){return dep[x]+dep[y]-dep[Lca(x,y)]*2;}
vector<int> t[2][N];
void modify(int typ,int pos,int x,int vl){
if(!x)return;
int up=t[typ][pos].size();
while(x<up){
t[typ][pos][x]+=vl;
x+=x&(-x);
}
}
int query(int typ,int pos,int x){
int res=0;
x=min(x,(int)(t[typ][pos].size()-1));
while(x){
res+=t[typ][pos][x];
x-=x&(-x);
}
return res;
}
int siz[N],F[N],rt,siz_tree;
int prt[N];bool vis[N];
void getroot(int u,int fa){
siz[u]=1;F[u]=0;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v==fa||vis[v])continue;
getroot(v,u);
siz[u]+=siz[v];
F[u]=max(F[u],siz[v]);
}
F[u]=max(F[u],siz_tree-siz[u]);
if(F[u]<F[rt])rt=u;
}
void divide(int u,int fa){
prt[u]=fa;vis[u]=1;
t[0][u].resize(siz_tree+1);
t[1][u].resize(siz_tree+1);
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(vis[v])continue;
F[rt=0]=siz_tree=siz[v];
getroot(v,u);
divide(rt,u);
}
}
void modify(int u,int vl){
for(int i=u;i;i=prt[i]){
modify(0,i,getdis(u,i),vl);
if(!prt[i])break;
modify(1,i,getdis(u,prt[i]),vl);
}
}
int query(int u,int vl){
int res=query(0,u,vl)+val[u];
for(int i=prt[u],last=u;i;last=i,i=prt[i]){
int d=vl-getdis(u,i);
if(d<0)continue;
res+=query(0,i,d)-query(1,last,d)+val[i];
}
return res;
}
void work(){
F[rt=0]=siz_tree=n;
getroot(1,0);
divide(rt,0);
}
int main(){
freopen("bzoj3730.in","r",stdin);
Log[0]=-1;for(int i=1;i<N;i++)Log[i]=Log[i>>1]+1;
n=read();m=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
add(u,v);
add(v,u);
}
getFa(1,0);
work();
for(int i=1;i<=n;i++)modify(i,val[i]);
for(int i=1;i<=m;i++){
int op=read(),x=read(),y=read();
x^=lastans,y^=lastans;
if(op)modify(x,y-val[x]),val[x]=y;
else printf("%d\n",lastans=query(x,y));
}
return 0;
}

BZOJ3730 震波 【动态点分治】*的更多相关文章

  1. bzoj3730 震波 [动态点分治,树状数组]

    传送门 思路 如果没有强制在线的话可以离线之后CDQ分治随便搞. 有了强制在线之后--可能可以二维线段树?然而我不会算空间. 然后我们莫名其妙地想到了动态点分治,然后这题就差不多做完了. 点分树有一个 ...

  2. BZOJ3730震波——动态点分治+线段树(点分树套线段树)

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  3. BZOJ3730 震波 | 动态点分治

    #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> # ...

  4. bzoj3730 [震波][动态树分治+线段树+LCA]

    震波 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 1573  Solved: 358[Submit][Status][Discuss] Descri ...

  5. 【BZOJ3730】震波 动态树分治+线段树

    [BZOJ3730]震波 Description 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土 ...

  6. 【BZOJ-3730】震波 动态点分治 + 树状数组

    3730: 震波 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 626  Solved: 149[Submit][Status][Discuss] D ...

  7. 【bzoj3730】震波 动态点分治+线段树

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  8. 【BZOJ3730】震波 - 动态点分治

    题意: Description 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]. 不幸的是,这片土地常常发生地震, ...

  9. bzoj 3730: 震波 动态点分治_树链剖分_线段树

    ##### 题目描述 : 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着 ...

  10. BZOJ 4372/3370 烁烁的游戏/震波 (动态点分治+线段树)

    烁烁的游戏 题目大意: 给你一棵$n$个节点的树,有$m$次操作,询问某个节点的权值,或者将与某个点$x$距离不超过$d$的所有节点的权值都增加$w$ 动态点分裸题 每个节点开一棵权值线段树 对于修改 ...

随机推荐

  1. Kotlin------类和对象(二)

    get/set方法 声明一个属性的完整语法是 var <propertyName>[: <PropertyType>] [= <property_initializer& ...

  2. jmeter-01 JMeter HTTP测试的各元件功能演示示例

    最小的测试将包括测试计划,线程组和一个或多个采样器. Jmeter HTTP测试的各元件演示示例 功能逻辑:wap官网(a.4399sy.com.hk),每个用户登录一次,发帖2次,发帖成功后注销退出 ...

  3. buffer与cache的区别

    top命令中有两项与内存相关的东西:buffer和cache.这两项与页高速缓存相关.磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的. 在linux内 ...

  4. 【Windows】netsh动态配置端口转发

    文章转载自傲风 使用多个虚拟机,将开发环境和工作沟通环境分开(即时通,办公系统都只能在windows下使用-),将开发环境的服务提供给外部访问时,需要在主机上通过代理配置数据转发. VirtualBo ...

  5. zen cart 空白页面的解决方案

    在安装zen cart 这套CMS时, 有时候会由于修改了某些页面或者是由于环境的某些组件的版本问题导致前台页面出现空白页, 由于在空白页面处没有任何提示, 并且在日志中也没有这样的出错提示, 导致在 ...

  6. wordpress启动

    wordpress启动 公司需要使用到wordpress 特意下载源码进行研究,才发现里面都是.php文件,需要运行php而不得不去配置运行环境 步骤如下 Wampserver32 使用的360安装的 ...

  7. python 语法错误记录

    1  Missing parameter end_time in docstring less... (Ctrl+F1) 参数位置错误 注意:只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明 ...

  8. ZooKeeper和Dubbo

    前言 Dubbo是阿里开源的一个分布式服务框架,但是阿里内部用的却是HSF(High-speed Service Framework).下面看看怎么使用吧. Zookeeper Dubbo是个RPC调 ...

  9. MySQL mha 高可用集群搭建

    [mha] MHA作为MySQL故障切换和主从提升的高可用软件,在故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一 ...

  10. LeetCode OJ:Generate Parentheses(括号生成)

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...