[BZOJ4372]烁烁的游戏
题面戳我
题意:
给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:
Q x:询问x的点权。
M x d w:将树上与节点x距离不超过d的节点的点权均加上w。
\(1≤n≤10^5\)
sol
和前一题是一样的[BZOJ3730]震波
这里是线段树的区间修改+单点查询。标记永久化就很舒服(不用pushup和pushdown)
code
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 100005;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
struct edge{int to,next;}a[N<<1];
int n,m,head[N],cnt,pa[N],dep[N],sz[N],son[N],top[N];
int root,sum,w[N],vis[N],fa[N],rt[N<<1],tot;
struct segment_tree{int ls,rs,v;}t[N*300];
void dfs1(int u,int f)
{
pa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up)
{
top[u]=up;
if (son[u]) dfs2(son[u],up);
for (int e=head[u];e;e=a[e].next)
if (a[e].to!=pa[u]&&a[e].to!=son[u])
dfs2(a[e].to,a[e].to);
}
int lca(int u,int v)
{
while (top[u]^top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
u=pa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int getdis(int u,int v){return dep[u]+dep[v]-(dep[lca(u,v)]<<1);}
void getroot(int u,int f)
{
sz[u]=1;w[u]=0;
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (v==f||vis[v]) continue;
getroot(v,u);
sz[u]+=sz[v];w[u]=max(w[u],sz[v]);
}
w[u]=max(w[u],sum-sz[u]);
if (w[u]<w[root]) root=u;
}
void solve(int u,int f)
{
fa[u]=f;vis[u]=1;int pre_sum=sum;
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (vis[v]) continue;
if (sz[v]>sz[u]) sum=pre_sum-sz[u];
else sum=sz[v];
root=0;
getroot(v,0);
solve(root,u);
}
}
void Modify(int &x,int l,int r,int ql,int qr,int v)
{
if (!x) x=++tot;
if (l>=ql&&r<=qr) {t[x].v+=v;return;}
int mid=l+r>>1;
if (ql<=mid) Modify(t[x].ls,l,mid,ql,qr,v);
if (qr>mid) Modify(t[x].rs,mid+1,r,ql,qr,v);
}
int Query(int x,int l,int r,int pos)
{
if (!x) return 0;
if (l==r) return t[x].v;
int mid=l+r>>1;
if (pos<=mid) return t[x].v+Query(t[x].ls,l,mid,pos);
else return t[x].v+Query(t[x].rs,mid+1,r,pos);
}
void PreModify()
{
int u=gi(),d=gi(),v=gi();
Modify(rt[u],0,n-1,0,d,v);
for (int i=u;fa[i];i=fa[i])
{
int dist=getdis(u,fa[i]);
if (d>=dist) Modify(rt[fa[i]],0,n-1,0,d-dist,v),Modify(rt[i+n],0,n-1,0,d-dist,v);
}
}
int PreQuery()
{
int u=gi(),res=Query(rt[u],0,n-1,0);
for (int i=u;fa[i];i=fa[i])
{
int dist=getdis(u,fa[i]);
res+=Query(rt[fa[i]],0,n-1,dist)-Query(rt[i+n],0,n-1,dist);
}
return res;
}
int main()
{
n=gi();m=gi();
for (int i=1;i<n;i++)
{
int u=gi(),v=gi();
a[++cnt]=(edge){v,head[u]};head[u]=cnt;
a[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
dfs1(1,0);dfs2(1,1);
sum=w[0]=n;
getroot(1,0);
solve(root,0);
while (m--)
{
char ch=getchar();
while (ch!='Q'&&ch!='M') ch=getchar();
if (ch=='Q') printf("%d\n",PreQuery());
else PreModify();
}
return 0;
}
[BZOJ4372]烁烁的游戏的更多相关文章
- BZOJ3730 震波 和 BZOJ4372 烁烁的游戏
"震波"题意 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser autoint Log ...
- BZOJ4372烁烁的游戏——动态点分治+线段树(点分树套线段树)
题目描述 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠.皮皮鼠会被 ...
- BZOJ4372 烁烁的游戏(动态点分治+线段树)
建出点分树,每个节点维护其作为点分树上lca对子树内点的贡献,线段树维护即可,同时另开一个线段树以减掉父亲重复的贡献. #include<iostream> #include<cst ...
- [BZOJ4372]烁烁的游戏(动态点分治+线段树)
和[BZOJ3730]震波几乎一样,每个点建两棵线段树分别代表它的管辖范围内以它为LCA的路径的贡献和它对父亲的贡献. 注意点分树上的点的距离在原树上不单调,所以不能有若距离超出限制就break之类的 ...
- BZOJ4372: 烁烁的游戏【动态点分治】
Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w ...
- BZOJ4372: 烁烁的游戏(动态点分治)
Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮 ...
- [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]
题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...
- 【BZOJ4372】烁烁的游戏(动态点分治)
[BZOJ4372]烁烁的游戏(动态点分治) 题面 BZOJ 大意: 每次在一棵书上进行操作 1.将离某个点u的距离不超过d的点的权值加上w 2.询问单点权值 题解 这题和前面那一道震波几乎是一模一样 ...
- 【BZOJ4372】烁烁的游戏 动态树分治+线段树
[BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...
随机推荐
- java处理json与对象的转化 递归
整个类是一个case,总结了我在使用java处理json的时候遇到的问题,还有级联关系的对象如何遍历,json和对象之间的转换! 对于对象json转换中遇到的问题我参考了一篇博客,http://blo ...
- WPF---Xaml中改变ViewModel的值
在开发中遇到实现如下需求的情景:一个输入框,旁边一个清空输入的按钮,当输入框中有内容时显示清空按钮,点击该按钮可以清空输入框内容,当输入框中无内容时隐藏按钮 当然这个需求使用wpf的绑定功能很容易实现 ...
- dnsmasq 做 DHCP 服务器
/etc/dnsmasq.conf #DNS服务器的地址,就是我的热点的地址 listen-address=192.168.1.1 #设置DHCP分配的地址范围和时间 dhcp-range=192.1 ...
- 织梦默认编辑器 按下回车生成br标签改为生成p标签
找到文件 \include\ckeditor\config.js 把 config.enterMode = CKEDITOR.ENTER_BR; config.shiftEnterMode = CKE ...
- 通过实例介绍Android App自动化测试框架--Unittest
1.为什么需要使用框架实现自动化测试 作为测试工程师,可能在代码能力上相比开发工程师要弱一点,所以我们在写脚本的时候就会相对容易的碰到更多的问题,如果有一个成熟的框架供给我们使用的话,可以帮助我们避免 ...
- Python print 输出到控制台 丢数据
import xlrd import sys,time data = xlrd.open_workbook("C:\Users\Administrator\Desktop\\new1.xls ...
- maven中的传递依赖和传递依赖的解除
例如创建三个maven工程A B C pom文件分别为 A <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...
- json字符串转换成json对象,json对象转换成字符串,值转换成字符串,字符串转成值
一.json相关概念 json,全称为javascript object notation,是一种轻量级的数据交互格式.采用完全独立于语言的文本格式,是一种理想的数据交换格式. 同时,json是jav ...
- flask中jinjia2模板使用详解2
接上文 注释的使用 在jinjia2模板中,使用{# #}进行代码注释,如下所示 运行后发现,注释不会被render出来 去掉空行 两种方法可以去掉jinjia2模板中的空白行,一是设置jinjia2 ...
- Windows10系统故障检测你知道多少-上海IT33
Windows 10作为微软公司最新的一款操作系统,从使用的方便和界面的整洁上来说,固然是很好的,但是其因为隐私问题,致使很多人不惜一切代价想要远离Windows 10这款操作系统.尽管Windows ...