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,把周围与他距 ...
随机推荐
- JavaScript(第三天)【数据类型】
学习要点: 1.typeof操作符 2.Undefined类型 3.Null类型 4.Boolean类型 5.Number类型 6.String类型 7.Object类型 ECMAScript中有5种 ...
- vue 中获取select 的option的value 直接click?
我刚开始遇到这个问题的时候 直接用的click进行dom操作获取value 但是发现并灭有什么作用 问了旁边大神 才想起来还有change这个操作 于是乎 答案有了解决方案 1.在你的select中添 ...
- python django的ManyToMany简述
Django的多对多关系 在Django的关系中,有一对一,一对多,多对多的关系 我们这里谈的是多对多的关系 ==我们首先来设计一个用于示例的表结构== # -*- coding: utf-8 -*- ...
- io文本加密
文本加密习题 package io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Inpu ...
- vue组件详解(二)——使用props传递数据
在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传递.父组件通过 props 给子组件下发数据,子组件通过事件给父组件发送消息.看看它们是怎么工作的. 一.基本用法 组件不仅仅 ...
- 2.sublime设置本地远程代码同步
1.打开编辑器输入框(Ctrl+Shift+P),并执行 2.回车后输入sftp 3.回车个后,右键项目 4.修改配置信息,保存
- redis入门(01)redis的下载和安装
参考链接: 命令手册 : http://www.redis.net.cn/order/ 菜鸟教程: http://www.runoob.com/redis/redis-install.html 一.概 ...
- 云计算(2)it 是什么
2015年,全世界在it上面的花费达到3亿8千亿美金之多. 云数据中心:核心基础架构,云计算的物理载体,提供数据处理.存储和高性能计算支撑,包括服务器.存储.冷却.机房空间和能耗管理等. 超大规模的云 ...
- OAuth2.0学习(1-13)oauth2.0 的概念:资源、权限(角色)和scope
mkk 关于资源的解释 : https://andaily.com/blog/?cat=19 resource用于将系统提供的各类资源进行分组管理, 每一个resource对应一个resource-i ...
- C#:多进程开发,控制进程数量
正在c#程序优化时,如果多线程效果不佳的情况下,也会使用多进程的方案,如下: System.Threading.Tasks.Task task=System.Threading.Tasks.Task. ...