题意:

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. 手游服务器端接入facebook的SDK

    手游如果支持facebook登录,就要接入facebook的登录SDK.刚好工作中自己做了这一块的接入功能现在记录分享下来提供一个参考. 当前只是接入了登录这个功能,先简单的说说接入facebook登 ...

  2. dp入门(先摆在这里,之后细细读)

    网址转载链接:  http://bbs.chinaunix.net/thread-4094539-1-1.html 动态规划:从新手到专家 Hawstein翻译 前言 我们遇到的问题中,有很大一部分可 ...

  3. BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)

    明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...

  4. HDU1061 - Rightmost Digit

    Given a positive integer N, you should output the most right digit of N^N. Input The input contains ...

  5. python异常处理,多线程,多进程

    什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错误. 当Pyth ...

  6. oracle查询表空间的位置

    SELECT * FROM Dba_Data_Files ddf WHERE ddf.tablespace_name = 'TablespaceName'; 以上SQL代码可以查询出表空间的所在路径和 ...

  7. HTTP请求和响应模式(B/S)(2)

    B/S          及浏览器/客服端模式 根据发送的状态码不同,显示response的状态不同

  8. C#-WebService基础01

    来自为知笔记(Wiz)

  9. 洛谷 P1301 魔鬼之城

    P1301 魔鬼之城 题目描述 在一个被分割为N*M个正方形房间的矩形魔鬼之城中,一个探险者必须遵循下列规则才能跳跃行动.他必须从(1, 1)进入,从(N, M)走出:在每一房间的墙壁上都写了一个魔法 ...

  10. map和multimap映射容器

    map容器 map所处理的数据与数据库表具有键值的记录非常相似,在键值与映射数据之间,建立一个数学上的映射关系.map容器的数据结构仍然採用红黑树进行管理.插入的元素键值不同意反复,所使用的结点元素的 ...