题意:

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次操作。
$1\leq N,M\leq 100000$
$1\leq u,v,x\leq N$
$1\leq value[i],y\leq 10000$
$0\leq k\leq N-1$

Output

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

题解:

动态点分治裸题……

今天终于弄清楚动态点分治是啥玩意了……就是用数据结构爬点分树,大致感觉其实跟树链剖分差不多?(依稀记得我貌似还有个紫荆花之恋的大坑?!)

这题用RMQLCA+线段树随便维护一下就好了……

ps:我写的ST表求LCA+线段树跑了1600ms……卡常数の不能……orzlhx树状数组+神秘优化跑了543ms

代码:

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
struct edge{
int v,next;
}a[];
struct node{
int v,ls,rs;
}t[];
int n,m,op,u,v,x,y,S,rt,ans=,tot=,tim=,cnt=,num[],f[],rt1[],rt2[],head[],mx[],dep[],siz[],dfn[],st[][],lg[];
bool used[];
void add(int u,int v){
a[++tot].v=v;
a[tot].next=head[u];
head[u]=tot;
}
void updata(int l,int r,int &u,int p,int x){
if(!u)u=++cnt;
t[u].v+=x;
if(l==r)return;
int mid=(l+r)/;
if(p<=mid)updata(l,mid,t[u].ls,p,x);
else updata(mid+,r,t[u].rs,p,x);
}
int query(int l,int r,int u,int p){
if(!u)return ;
if(l==r)return t[u].v;
int mid=(l+r)/;
if(p<=mid)return query(l,mid,t[u].ls,p);
else return query(mid+,r,t[u].rs,p)+t[t[u].ls].v;
}
int getdis(int u,int v){
int l=dep[u]+dep[v],tmp;
u=dfn[u];
v=dfn[v];
if(u>v)swap(u,v);
tmp=lg[v-u+];
return l-min(st[u][tmp],st[v-(<<tmp)+][tmp])*;
}
void dfs(int u,int fa,int dpt){
dfn[u]=++tim;
dep[u]=dpt;
st[tim][]=dep[u];
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa){
dfs(v,u,dpt+);
st[++tim][]=dep[u];
}
}
}
void getrt(int u,int fa){
siz[u]=;
mx[u]=;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa&&!used[v]){
getrt(v,u);
siz[u]+=siz[v];
mx[u]=max(mx[u],siz[v]);
}
}
mx[u]=max(mx[u],S-mx[u]);
if(mx[u]<mx[rt])rt=u;
}
void getn(int u,int fa,int ls){
updata(,n-,rt1[ls],getdis(u,ls),num[u]);
if(f[ls])updata(,n-,rt2[ls],getdis(u,f[ls]),num[u]);
siz[u]=;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa&&!used[v]){
getn(v,u,ls);
siz[u]+=siz[v];
}
}
}
void divide(int u){
getn(u,,u);
used[u]=true;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(!used[v]){
S=siz[v];
rt=;
getrt(v,);
f[rt]=u;
divide(rt);
}
}
}
void LHX_AK_IOI(int u,int k){
for(int now=u;now;now=f[now]){
updata(,n-,rt1[now],getdis(u,now),k-num[u]);
if(f[now])updata(,n-,rt2[now],getdis(u,f[now]),k-num[u]);
}
num[u]=k;
}
int LHX_AK_NOI(int u,int k){
int ret=;
for(int now=u;now;now=f[now]){
if(getdis(u,now)<=k)ret+=query(,n-,rt1[now],k-getdis(u,now));
if(f[now]&&getdis(u,f[now])<=k)ret-=query(,n-,rt2[now],k-getdis(u,f[now]));
}
return ret;
}
int main(){
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&num[i]);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(,,);
lg[]=-;
for(int i=;i<=tim;i++)lg[i]=lg[i>>]+;
for(int i=;(<<i)<=tim;i++){
for(int j=;j<=tim-(<<i)+;j++){
st[j][i]=min(st[j][i-],st[j+(<<i-)][i-]);
}
}
mx[rt=]=inf;
S=n;
getrt(,);
divide(rt);
for(int i=;i<=m;i++){
scanf("%d%d%d",&op,&x,&y);
x^=ans,y^=ans;
if(op==){
ans=LHX_AK_NOI(x,y);
printf("%d\n",ans);
}else LHX_AK_IOI(x,y);
}
return ;
}

【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. bzoj 3730: 震波 动态点分治_树链剖分_线段树

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

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

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

随机推荐

  1. POSIX Threads

    POSIX Threads, usually referred to as pthreads, is an execution model that exists independently from ...

  2. css pointer-event

    详见:张鑫旭 CSS3 pointer-events:none应用举例及扩展 pointer-events:none ,可以使事件穿透, 如: 2 覆盖在 1 上面. 给 2 设置 pointer-e ...

  3. 基于selectors模块实现并发的FTP

    import socketimport os,sysBASE_DIR = os.path.dirname(os.path.abspath(__file__)) class selectFtpClien ...

  4. 为什么使用GitHub

    GitHub的特点: 1.开源式分布版本管理系统 2.开源项目集中的代码库 3.所有略有规模的公司都在使用 GitHub的功能介绍: 1.记录多个版本 2.查看历史操作,可以进行版本吧回退和前进的控制 ...

  5. Java 应用运维

    作者:http://blogread.cn/it/article/4918?f=wb 出处:http://blogread.cn/it/article/4918?f=wb Java应用运维    出处 ...

  6. springmvcjson中文乱码处理

    在sping.xml中增加配置信息 <bean class="org.springframework.web.servlet.mvc.method.annotation.Request ...

  7. 安装SSH、配置SSH无密码登录 ssh localhost

    集群.单节点模式都需要用到 SSH 登陆(类似于远程登陆,你可以登录某台 Linux 主机,并且在上面运行命令),Ubuntu 默认已安装了 SSH client,此外还需要安装 SSH server ...

  8. oracle间隔分区

    http://blog.csdn.net/rznice/article/details/55048876

  9. Apache Tez 0.7、0.83、 0.82 安装、调试笔记

    ———————————————————— 准备 Tez 编译环境 ———————————————————— 1 需要的支持 tez0.7 需要 Hadoop 2.60 以上 2 需要的 linux 相 ...

  10. [Oracle] Merge语句

    Merge的语法例如以下: MERGE [hint] INTO [schema .] table [t_alias] USING [schema .] { table | view | subquer ...