BZOJ 4372 烁烁的游戏
Description
背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠。
题意:
给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠。
烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠。皮皮鼠会被烁烁吸引,所以会一直待在节点上不动。
烁烁很好奇,在当前时刻,节点u有多少个他的好朋友---皮皮鼠。
大意:
给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:
Q x:询问x的点权。
M x d w:将树上与节点x距离不超过d的节点的点权均加上w。
Input
第一行两个正整数:n,m
接下来的n-1行,每行三个正整数u,v,代表u,v之间有一条边。
接下来的m行,每行给出上述两种操作中的一种。
Output
对于每个Q操作,输出当前x节点的皮皮鼠数量。
Sample Input
1 2
1 4
1 5
2 3
2 7
5 6
M 1 1 2
Q 5
M 2 2 3
Q 3
M 1 2 1
Q 2
Sample Output
3
6
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX 120000
struct Node
{
int next,to;
}edge[MAX<<];
int num,head[MAX];
int dep[MAX],fa[MAX],pos,size[MAX],minsize,root;
int FA[MAX],son[MAX],top[MAX],Size;
int lazy[MAX*];
int ch[MAX*][],RT[MAX<<],n,m;
int ans,val[MAX];
bool vis[MAX];
inline int gi()
{
int x=,flag=;
char ch=getchar();
while (ch<''||ch>'')
{
if (ch=='-') flag=-;
ch=getchar();
}
while (ch>=''&&ch<='')
{
x=(x<<)+(x<<)+ch-'';
ch=getchar();
}
return x*flag;
}
inline void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void dfs1(int x,int pa)
{
size[x]=;
dep[x]=dep[pa]+;
for (int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa) continue;
fa[v]=x;
dfs1(v,x);
size[x]+=size[v];
if (size[son[x]]<size[v])
son[x]=v;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
if (son[x])
dfs2(son[x],tp);
for (int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==fa[x]||v==son[x]) continue;
dfs2(v,v);
}
}
int lca(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if (dep[x]<dep[y]) return x;
return y;
}
int dis(int x,int y)
{
return dep[x]+dep[y]-(dep[lca(x,y)]<<);
}
void get_root(int x,int pa)
{
size[x]=;
int ret=;
for (int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||vis[v]) continue;
get_root(v,x);
size[x]+=size[v];
if (size[v]>ret) ret=size[v];
}
if (Size-size[x]>ret) ret=Size-size[x];
if (ret<minsize) minsize=ret,root=x;
}
void solve(int x,int pa)
{
vis[x]=;
FA[x]=pa;
for (int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (vis[v]) continue;
minsize=n;Size=size[v];
get_root(v,x);
solve(root,x);
}
}
void update(int &rt,int l,int r,int L,int R,int w)
{
if (!rt) rt=++pos;
if (l>=L&&r<=R)
{lazy[rt]+=w;return;}
int mid=(l+r)>>;
if (L<=mid) update(ch[rt][],l,mid,L,R,w);
if (R>mid) update(ch[rt][],mid+,r,L,R,w);
}
int query(int rt,int l,int r,int x)
{
if (!rt) return ;
if (l==r)
return lazy[rt];
int mid=(l+r)>>;
if (x<=mid) return query(ch[rt][],l,mid,x)+lazy[rt];
else return query(ch[rt][],mid+,r,x)+lazy[rt];
}
void change(int u,int k,int w)
{
update(RT[u],,n,,k,w);
for (int i=u;FA[i];i=FA[i])
{
int d=dis(u,FA[i]);
if (d>k) continue;
update(RT[FA[i]],,n,,k-d,w);
update(RT[i+n],,n,,k-d,w);
}
}
void ask(int u)
{
ans+=query(RT[u],,n,);
for (int i=u;FA[i];i=FA[i])
{
int d=dis(u,FA[i]);
ans+=query(RT[FA[i]],,n,d);
ans-=query(RT[i+n],,n,d);
}
}
int main()
{int u,v;
char s[];
cin>>n>>m;
for (int i=;i<=n-;i++)
{
u=gi();v=gi();
add(u,v);add(v,u);
}
dfs1(,);
dfs2(,);
minsize=Size=n;
get_root(,);
solve(root,);
ans=;
for (int i=;i<=m;i++)
{
scanf("%s",s);
if (s[]=='Q')
{
ans=;
int x=gi();
ask(x);
printf("%d\n",ans);
}
else
{
int u=gi(),k=gi(),w=gi();
change(u,k,w);
}
}
return ;
}
BZOJ 4372 烁烁的游戏的更多相关文章
- 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 一样,可以直接双倍经验了: 但要注意一下,树状数组不能查询 ...
- bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树
[Submit][Status][Discuss] Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳 ...
- BZOJ3730 震波 和 BZOJ4372 烁烁的游戏
"震波"题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Log ...
- BZOJ 4372/3370 烁烁的游戏/震波 (动态点分治+线段树)
烁烁的游戏 题目大意: 给你一棵$n$个节点的树,有$m$次操作,询问某个节点的权值,或者将与某个点$x$距离不超过$d$的所有节点的权值都增加$w$ 动态点分裸题 每个节点开一棵权值线段树 对于修改 ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...
- bzoj 3991: [SDOI2015]寻宝游戏 虚树 set
目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...
- bzoj 3232: 圈地游戏
bzoj 3232: 圈地游戏 01分数规划,就是你要最大化\(\frac{\sum A}{\sum B}\),就二分这个值,\(\frac{\sum A}{\sum B} \geq mid\) \( ...
- 【BZOJ4372】烁烁的游戏 动态树分治+线段树
[BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...
随机推荐
- 2018.3.29 div格式设置
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- winform 适配high dpi
在 mainifest文件中添加:(新建mainifest文件的时候以下内容是有的,只要取消注释就可以了) <compatibility xmlns="urn:schemas-micr ...
- 课堂测试ch06
课堂测试ch06 下面代码中,对数组x填充后,采用直接映射高速缓存,所有对x和y引用的命中率为(D) A. 1 B. 1/4 C. 1/2 D. 3/4 解析:在填充了之后,对于x和y数组,只有在引用 ...
- JavaScript 相关知识
一.数组 var a = [1,2,3,4]; console.log(a.length); a.push(5); console.log(a); // [1, 2, 3, 4, 5] var r ...
- JAVA中if多分支和switch的优劣性。
Switch多分支语句switch语句是多分支选择语句.常用来根据表达式的值选择要执行的语句.例如,在某程序中,要求将输入的或是获取的用0-6代表的星期,转换为用中文表示的星期.该需求通过伪代码描述的 ...
- OSI七层协议模型、TCP/IP四层模型学习笔记
1. OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行 ...
- 解决background图片拉伸问题
ImageView中XML属性src和background的区别: background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸.src是图片内容(前 ...
- 成功案例分享:raid5两块硬盘掉线数据丢失恢复方法
1. 故障描述 本案例是HP P2000的存储vmware exsi虚拟化平台,由RAID-5由10块lT硬盘组成,其中6号盘是热备盘,由于故障导致RAID-5磁盘阵列的两块盘掉线,表现为两块硬 ...
- js判断flash文件是否加载完毕
轮询判断加载进度 img的加载完成有onload方法,一直不知道该怎么判断swf文件是否加载完毕了? 在应用中使用了轮询判断加载进度值PercentLoaded是否达到100,经测试,可以达到效果. ...
- slf4j 与 log4j2 实战讲解与日志分割
这两天搭建项目的时候用到log4j2在这里把自己的问题与了解拿出来与大家分享一下. 1.为什我要用 因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用l ...