[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,把周围与他距 ...
随机推荐
- 浅显总结ASCII Unicode UTF-8的区别
如果觉得此地排版不好,欢迎访问我的博客 浅显总结ASCII Unicode UTF-8的区别 制作表单时,为了追求更好的用户交互体验,常常会有提示性的内容,比如提醒用户字符的限制.由于英文,中文字符的 ...
- [CJOJ2410]数列操作d
[CJOJ2410]数列操作d 标签: 线段树 题解 没时间写题了,我来嘴巴AC吧. 注意区间加的这个值不是 确定的,随着元素位置的变化而改变. 只需要能维护这个东西剩下的就很好做了. 那么\(x*( ...
- mvc get image 500
mvc中get图片时报500错误 很奇怪,突然变500错误了,一番查找之后发现原来是因为mimeType重复定义的原因,吐血.. http://stackoverflow.com/questions/ ...
- js中的写出想jquery中的函数一样调用
1.IIFE: Immediately-Invoked function Expression 函数模块自调用 2.代码实现 <!DOCTYPE html> <html lang=& ...
- PHP结合Redis来限制用户或者IP某个时间段内访问的次数
$redis = new Redis(); $redis->connect('127.0.0.1', 6379); //获取客户端真实ip地址 function get_real_ip(){ s ...
- 深入理解Python的字符编码
原文:http://lukejin.iteye.com/blog/598303 在处理中文的时候,我们有时候会碰到中文乱码的问题. 究其根本原因是正确的字节序列按照错误的编码方式解码成字符 或者正确的 ...
- UVA - 11292 Dragon of Loowater 贪心
贪心策略:一个直径为X的头颅,应该让雇佣费用满足大于等于X且最小的骑士来砍掉,这样才能使得花费最少. AC代码 #include <cstdio> #include <cmath&g ...
- MongoDB,分组,聚合
使用聚合,db.集合名.aggregate- 而不是find 管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数.MongoDB的聚合管道将MongoDB文档在一个管道处理完 ...
- Python+Selenium基础篇之1-环境搭建
Python + Selenium 自动化环境搭建过程 1. 所需组建 1.1 Selenium for python 1.2 Python 1.3 Notepad++ 作为刚初学者,这里不建议使用P ...
- java8在Collection中新增加的方法removeIf
记得我在以前找工作的经历中,遇到过一个面试官问过我一个很基础的问题.问题是:有一个List中有10个元素,我现在想从中删除3个元素,请问怎么做?我当时也没想,就直接说,List的有自带的remove方 ...