【BZOJ4372】烁烁的游戏(动态点分治)
【BZOJ4372】烁烁的游戏(动态点分治)
题面
BZOJ
大意:
每次在一棵书上进行操作
1.将离某个点u的距离不超过d的点的权值加上w
2.询问单点权值
题解
这题和前面那一道震波几乎是一模一样的
只不过把两个操作的区间问题给换了一下
现在是区间修改,单点询问而已
#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;}e[MAX<<1],E[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};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;
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 dep[u]+dep[v]-dep[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 lz;
}t[MAX*150];
int tot,rt[MAX<<1];
void Modify(int &now,int l,int r,int L,int R,int w)
{
if(!now)now=++tot;
if(l==L&&r==R){t[now].lz+=w;return;}
int mid=(l+r)>>1;
if(R<=mid)Modify(t[now].ls,l,mid,L,R,w);
else if(L>mid)Modify(t[now].rs,mid+1,r,L,R,w);
else Modify(t[now].ls,l,mid,L,mid,w),Modify(t[now].rs,mid+1,r,mid+1,R,w);
}
int Query(int now,int l,int r,int pos)
{
if(!now)return 0;
if(l==r)return t[now].lz;
int mid=(l+r)>>1;
if(pos<=mid)return Query(t[now].ls,l,mid,pos)+t[now].lz;
else return Query(t[now].rs,mid+1,r,pos)+t[now].lz;
}
void PModify(int u,int K,int w)
{
Modify(rt[u],0,n,0,K,w);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
if(K<dist)continue;
Modify(rt[Fa[i]],0,n,0,K-dist,w);
Modify(rt[i+n],0,n,0,K-dist,w);
}
}
int PQuery(int u)
{
int ret=Query(rt[u],0,n,0);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
ret+=Query(rt[Fa[i]],0,n,dist);
ret-=Query(rt[i+n],0,n,dist);
}
return ret;
}
int main()
{
n=read();Q=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);dfs2(1,1);
minr=Size=n;Getroot(1,0);
DFS(root,0);
char ch[2];
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='M')
{
int u=read(),K=read(),w=read();
PModify(u,K,w);
}
else printf("%d\n",PQuery(read()));
}
return 0;
}
【BZOJ4372】烁烁的游戏(动态点分治)的更多相关文章
- BZOJ4372烁烁的游戏——动态点分治+线段树(点分树套线段树)
题目描述 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠.皮皮鼠会被 ...
- [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]
题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...
- [BZOJ4372]烁烁的游戏(动态点分治+线段树)
和[BZOJ3730]震波几乎一样,每个点建两棵线段树分别代表它的管辖范围内以它为LCA的路径的贡献和它对父亲的贡献. 注意点分树上的点的距离在原树上不单调,所以不能有若距离超出限制就break之类的 ...
- BZOJ4372: 烁烁的游戏(动态点分治)
Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮 ...
- 【BZOJ4372】烁烁的游戏 动态树分治+线段树
[BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...
- 【bzoj4372】烁烁的游戏 动态点分治+线段树
题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...
- bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树
[Submit][Status][Discuss] Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳 ...
- bzoj 4372 烁烁的游戏——动态点分治+树状数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372 和 bzoj 3070 震波 是一个套路.注意区间修改的话,树状数组不能表示 dis ...
- bzoj 4372 烁烁的游戏 —— 动态点分治+树状数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372 本以为和 bzoj3730 一样,可以直接双倍经验了: 但要注意一下,树状数组不能查询 ...
- BZOJ4372: 烁烁的游戏【动态点分治】
Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w ...
随机推荐
- URL中特殊符号的处理
问题描述 我们在对接第三方系统的时候通常需要get或post来传输数据,但此时如果参数中存在&% #*!包括空格等特殊符号的时候就无法正常请求具体表现在参数获取不正确或者获取不到参数,甚至有时 ...
- MongoDB安装篇-Win7 X64
介绍 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库 ...
- GitHub中开启二次验证Two-factor authentication,如何在命令行下更新和上传代码
最近在使用GitHub管理代码,在git命令行管理代码时候遇到一些问题.如果开起了二次验证(Two-factor authentication两个要素认证),命令行会一直提示输入用户名和密码.查找了一 ...
- centos7使用docker部署gitlab-ce-zh应用
1.国内拉取镜像比较慢,所以这里采用DaoCloud源. # curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http ...
- maven项目打包的时候,*Mapper.xml 文件会打不不进去解决办法
打包的时候,不同版本的 Eclipse 还有IDEA 会有打包打不进去Mapper.xml 文件,这个时候要加如下代码, 在<build> 标签内加入即可 <resources> ...
- levmar ndk 编译
levmar是一个强大的和高效率的C/C++库,采用Levenberg - 马奎德(LM)优化算法, 主要是为了解决非线性最小二乘问题.官网是:http://users.ics.forth. ...
- Java经典编程题50道之四十八
某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字, 再将第一位和第四位交换,第二位和第三位交换. public ...
- mongodb Decimal Spring data mongodb Decimal128 SpringMvc 序列化字符串 json converter
Mongodb 3.4 就开始支持Decimal 类型,解决double的精度问题,但是不太好用,MapReduce的时候Array.sum 也不能计算 Decimal.比较坑,但是聚合可以用 Spr ...
- 安装CentOS7
安装环境:虚拟机*1 使用软件:CentOS7镜像*1 安装过程: 虚拟机配置步骤(主要部分): 1.安装为Linux:CentOS 64位 2.分配1G内存(若需求大可根据实际情况分配) 3.分配4 ...
- MySQL高级学习笔记
1. 变量相关 临时变量 -- 定义在函数体或存储过程中的变量 -- 用法在讲函数时会提到 用户变量,也称会话变量 -- 用户变量只对当前连接用户有效,其他连接用户无法访问 -- 使用 @ 标识符声明 ...