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,把周围与他距 ...
随机推荐
- hibernate框架学习笔记11:Criteria查询详解
创建实体类对象: package domain; import java.util.HashSet; import java.util.Set; //客户实体 public class Custome ...
- Beta 第七天
今天遇到的困难: 构造新适配器的时候出现了某些崩溃的问题 ListView监听器有部分的Bug 今天完成的任务: 陈甘霖:完成相机调用和图库功能,完成阿尔法项目遗留下来的位置调用问题,实现百度定位 蔡 ...
- 每日冲刺报告-Day4
敏捷冲刺报告--Day4 情况简介 今天完成前端后端任务对接, GUI主体编写 任务进度 赵坤: 完成后端爬虫 李世钰: 前后端对接, GUI编写 黄亦薇:召集小组成员开会,帮助查找资料,寻找BUG ...
- SciPy - 科学计算库(上)
SciPy - 科学计算库(上) 一.实验说明 SciPy 库建立在 Numpy 库之上,提供了大量科学算法,主要包括这些主题: 特殊函数 (scipy.special) 积分 (scipy.inte ...
- 库函数atoi
函数名:atoi 功能: 把一个字符串转换成一个整数. 看似简单,主要是情况太多,需要注意考虑. 测试代码: Test(NULL); Test(""); Test("12 ...
- Android接受验证码自动填入功能(源码+已实现+可用+版本兼容)
实际应用开发中,会经常用到短信验证的功能,这个时候如果再让用户就查看短信.然后再回到界面进行短信的填写,难免有多少有些不方便,作为开发者.本着用户至上的原则我们也应该来实现验证码的自动填写功能,还有一 ...
- C#系统服务安装
转载 http://blog.csdn.net/vvhesj/article/details/8349615 1.1创建WindowsService项目 导入需要的引用比如System.configu ...
- CentOS搭建Git服务器及权限管理
声明:本教程,仅作为配置的记录,细节不展开,需要您有一点linux的命令基础,仅作为配置参考. 1. 系统环境 系统: Linux:CentOS 7.2 64位 由于CentOS已经内置了OpenSS ...
- python 基础 set 集合类型补充
为啥今天又重提这个数据类型呢?平时用的少,等要用起来的时候才发现,自己对这块啥都不知道了,so,今天就把这块再梳理一下咯. 一.set集合,是一个无序且不重复的元素集合.这一点是非常重要的. 二.集合 ...
- MQTT和paho(一)
参考链接:http://blog.csdn.net/yangzl2008/article/details/8861069 一.mqtt 1.简单介绍 http://mqtt.org/software ...