题意:

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. ZBrush中移动笔刷介绍

    移动笔刷是ZBrush®笔刷中举足轻重的一项,利用移动笔刷可以实现移动顶点的功能,还能改变模型的某一个点和某一位置.本文内容向大家介绍ZBrush®中移动笔刷以便大家熟悉它的用法和特性. 移动笔刷 可 ...

  2. 前端框架easyui layout, Tabs,tree

    一.三大前端框架的 1.easyui=jquery+html4(用来做后台的管理界面) 不要钱,开发速度快,不好看,不支持响应式 2.bootstrap=jquery+html5 好看,开发速度快,部 ...

  3. Eclipse中使用GIT更新项目

    GIT更新项目: 右击项目——Team——Pull:

  4. 路飞学城Python-Day37

    36-多表查询练习 37-权限管理 1.创建账号 本地账号 create user 'panda' @ 'loacalhost' inentified by'123' 远程账号 create user ...

  5. github删除项目or仓库

    1. 登录 github (要注册账号) 2. 登录后点击右上侧头像,选择 Your profile . 3. 选择Repositories,可以查看已有的库,选择要删除的库进入. 4. 选择Sett ...

  6. Linux 网络属性管理

    Linux网络基础管理-1:IPv4 地址分类:  点分十进制:0.0.0.0-255.255.255.255  A类: 0 0000000 - 0 1111111: 1-127 网络数:126, 1 ...

  7. python_购物车程序

    #需求1.启动程序后,让用户输入工资,然后打印商品列表2.允许用户根据商品编号购买商品3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒4.可随时退出,退出时,打印已购买商品和余额 #先定义 ...

  8. NOIP2018提高组金牌训练营——搜索专题

    NOIP2018提高组金牌训练营——搜索专题 1416 两点 福克斯在玩一款手机解迷游戏,这个游戏叫做”两点”.基础级别的时候是在一个n×m单元上玩的.像这样: 每一个单元有包含一个有色点.我们将用不 ...

  9. 《你又怎么了我错了行了吧》【Beta】Scrum Meeting 2

    第二天 日期:2019/6/25 前言: 第2次会议在女生宿舍召开 确认编码阶段已经完成,继续测试项目 1.1 今日完成任务情况以及明日任务安排 姓名 当前阶段任务 下一阶段任务 刘 佳 完善了未开发 ...

  10. 前端和后台对接时对sign加密方法

    前端和后台对接时对sign加密方法 /*后台php对接进行sign标签加密 1 获取向后台请求的数据data(key/value方式),可以是个对象(obj),也可以是数组(arr); 2 将数据的k ...