【BZOJ3730】震波(动态点分治)

题面

BZOJ

题意

给定一棵树,

每次询问到一个点的距离\(<=K\)的点的权值之和

动态修改权值,

强制在线

题解

正常的\(DP\)???

很简单呀。

每次暴力往父亲跳,不断的加值,

然后容斥一下就行了

现在要动态维护

就维护一下动态点分治

但是现在记录起来没那么容易了

于是开两棵线段树

每次做一下差

不断暴跳点分树的父亲就行啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 120000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next,w,rt;}e[MAX<<1],E[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w,0};h[u]=cnt++;}
/************************************************************************/
int dfn[MAX],top[MAX],dep[MAX],ssize[MAX],hson[MAX],fa[MAX];
int dis[MAX];
void dfs1(int u,int ff)
{
fa[u]=ff;ssize[u]=1;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff)continue;
dis[v]=dis[u]+e[i].w;
dfs1(v,u);
ssize[u]+=ssize[v];
if(ssize[hson[u]]<ssize[v])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int Dis(int u,int v)
{
return dis[u]+dis[v]-dis[LCA(u,v)]*2;
}
/************************************************************************/
int sum[MAX],size[MAX],Fa[MAX];
int n,Q,m,val[MAX];
int Size,root,minr;
bool vis[MAX];
void Getroot(int u,int ff)
{
size[u]=1;
int ret=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff||vis[v])continue;
Getroot(v,u);
size[u]+=size[v];
ret=max(ret,size[v]);
}
ret=max(ret,Size-size[u]);
if(ret<minr)minr=ret,root=u;
}
void DFS(int u,int ff)
{
vis[u]=true;Fa[u]=ff;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
minr=n;Size=size[v];
Getroot(v,u);
DFS(root,u);
}
}
struct Node
{
int ls,rs;
int v;
}t[MAX*150];
int tot,rt[MAX<<1];
void Modify(int &now,int l,int r,int pos,int w)
{
if(!now)now=++tot;t[now].v+=w;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)Modify(t[now].ls,l,mid,pos,w);
else Modify(t[now].rs,mid+1,r,pos,w);
}
int Query(int now,int l,int r,int L,int R)
{
if(!now)return 0;
if(L<=l&&r<=R)return t[now].v;
int ret=0,mid=(l+r)>>1;
if(L<=mid)ret+=Query(t[now].ls,l,mid,L,R);
if(R>mid)ret+=Query(t[now].rs,mid+1,r,L,R);
return ret;
}
void PModify(int u,int w)
{
Modify(rt[u],0,n,0,w);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
Modify(rt[Fa[i]],0,n,dist,w);
Modify(rt[i+n],0,n,dist,w);
}
}
int PQuery(int u,int K)
{
int ret=Query(rt[u],0,n,0,K);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
if(dist>K)continue;
ret+=Query(rt[Fa[i]],0,n,0,K-dist);
ret-=Query(rt[i+n],0,n,0,K-dist);
}
return ret;
}
int main()
{
n=read();Q=read();
for(int i=1;i<=n;++i)val[i]=read();
for(int i=1,u,v;i<n;++i)u=read(),v=read(),Add(u,v,1),Add(v,u,1);
dfs1(1,0);dfs2(1,1);
minr=Size=n;Getroot(1,0);
DFS(root,0);
for(int i=1;i<=n;++i)PModify(i,val[i]);
int ans=0;
while(Q--)
{
int opt=read();
if(opt)
{
int u=read()^ans,v=read()^ans;
PModify(u,v-val[u]);
val[u]=v;
}
else
{
int u=read()^ans,K=read()^ans;
ans=PQuery(u,K);
printf("%d\n",ans);
}
}
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. HashMap----工作原理

    先来些简单的问题 "你用过HashMap吗?" "什么是HashMap?你为什么用到它?" 几乎每个人都会回答"是的",然后回答HashMa ...

  2. angularjs中类似textarea的换行、空格处理

    背景 今天测试人员测试出来一个显示数据的页面,没有换行. 原因剖析 这个页面是从一个<textarea>的页面拿到的数据,存到数据库中后再返回来的. 1. 知道这点之后,就有了调查方向了: ...

  3. Hive metastore源码阅读(二)

    最近随着项目的深入,发现hive meta有些弊端,就是你会发现它的元数据操作与操作物理集群的代码耦合在一起,非常不利于扩展.比如:在create_table的时候同时进行路径校验及创建,如下代码: ...

  4. 浅谈PHP答题卡识别(一)

    最近期末考试考完了,我们也要放寒假了.于是突发奇想,想用PHP写一个答题卡识别程序.已经实现了一些,现分享给大家. 具体的步骤如下: 上传答题卡=>图片二值化(已实现)=>寻找定位点(已实 ...

  5. Linux常用命令详解(一) -- 处理目录常用命令

    ls:列出目录    作用:查看linux文件夹包含的文件以及其权限(包括目录.文件夹.文件权限)和目录信息等    命令格式:ls [选项] [文件或目录]    选项或参数:            ...

  6. ubuntu16.04~qt 5.8无法输入中文

    编译fcitx-qt需要cmake,安装cmake命令,如果已经安装,请略过. sudo apt-get install cmake 安装 fcitx-libs-dev sudo apt-get in ...

  7. centos/linux下的安装Tomcat

    1.启动tomcat时候需要JDK依赖 如果没有安装的请移步到该链接Centos/linux下的JDK安装 2.从官网上下载tomcat压缩包 wget -c http://apache.fayea. ...

  8. 使用Git的hook实现代码的自动部署

    这个功能非常的好用,可以省去诸多麻烦!我自己也是摸索了好久,才完全掌握的.希望能对大家有所帮助! 1,首先在我的阿里云服务器上已经创建好了一个代码远程的管理仓库,/srv/cmp.git 2, 在服务 ...

  9. javascript 函数详解

    一.函数的一些基础概念: 1.js中的函数使用function来声明. 2.关于return: 2.1  函数在执行到return语句后悔立即停止并退出,return后面的代码永远不会得到执行: 2. ...

  10. 《android开发艺术探索》读书笔记(十五)--Android性能优化

    接上篇<android开发艺术探索>读书笔记(十四)--JNI和NDK编程 No1: 如果<include>制定了这个id属性,同时被包含的布局文件的根元素也制定了id属性,那 ...