【BZOJ4372】烁烁的游戏(动态点分治)

题面

BZOJ

大意:

每次在一棵书上进行操作

1.将离某个点u的距离不超过d的点的权值加上w

2.询问单点权值

题解

这题和前面那一道震波几乎是一模一样的

只不过把两个操作的区间问题给换了一下

现在是区间修改,单点询问而已

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 120000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<1],E[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
/************************************************************************/
int dfn[MAX],top[MAX],dep[MAX],ssize[MAX],hson[MAX],fa[MAX];
int dis[MAX];
void dfs1(int u,int ff)
{
fa[u]=ff;ssize[u]=1;dep[u]=dep[ff]+1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff)continue;
dfs1(v,u);
ssize[u]+=ssize[v];
if(ssize[hson[u]]<ssize[v])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int Dis(int u,int v)
{
return dep[u]+dep[v]-dep[LCA(u,v)]*2;
}
/************************************************************************/
int sum[MAX],size[MAX],Fa[MAX];
int n,Q,m,val[MAX];
int Size,root,minr;
bool vis[MAX];
void Getroot(int u,int ff)
{
size[u]=1;
int ret=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff||vis[v])continue;
Getroot(v,u);
size[u]+=size[v];
ret=max(ret,size[v]);
}
ret=max(ret,Size-size[u]);
if(ret<minr)minr=ret,root=u;
}
void DFS(int u,int ff)
{
vis[u]=true;Fa[u]=ff;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
minr=n;Size=size[v];
Getroot(v,u);
DFS(root,u);
}
}
struct Node
{
int ls,rs;
int lz;
}t[MAX*150];
int tot,rt[MAX<<1];
void Modify(int &now,int l,int r,int L,int R,int w)
{
if(!now)now=++tot;
if(l==L&&r==R){t[now].lz+=w;return;}
int mid=(l+r)>>1;
if(R<=mid)Modify(t[now].ls,l,mid,L,R,w);
else if(L>mid)Modify(t[now].rs,mid+1,r,L,R,w);
else Modify(t[now].ls,l,mid,L,mid,w),Modify(t[now].rs,mid+1,r,mid+1,R,w);
}
int Query(int now,int l,int r,int pos)
{
if(!now)return 0;
if(l==r)return t[now].lz;
int mid=(l+r)>>1;
if(pos<=mid)return Query(t[now].ls,l,mid,pos)+t[now].lz;
else return Query(t[now].rs,mid+1,r,pos)+t[now].lz;
}
void PModify(int u,int K,int w)
{
Modify(rt[u],0,n,0,K,w);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
if(K<dist)continue;
Modify(rt[Fa[i]],0,n,0,K-dist,w);
Modify(rt[i+n],0,n,0,K-dist,w);
}
}
int PQuery(int u)
{
int ret=Query(rt[u],0,n,0);
for(int i=u;Fa[i];i=Fa[i])
{
int dist=Dis(u,Fa[i]);
ret+=Query(rt[Fa[i]],0,n,dist);
ret-=Query(rt[i+n],0,n,dist);
}
return ret;
}
int main()
{
n=read();Q=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);dfs2(1,1);
minr=Size=n;Getroot(1,0);
DFS(root,0);
char ch[2];
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='M')
{
int u=read(),K=read(),w=read();
PModify(u,K,w);
}
else printf("%d\n",PQuery(read()));
}
return 0;
}

【BZOJ4372】烁烁的游戏(动态点分治)的更多相关文章

  1. BZOJ4372烁烁的游戏——动态点分治+线段树(点分树套线段树)

    题目描述 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠.皮皮鼠会被 ...

  2. [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]

    题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...

  3. [BZOJ4372]烁烁的游戏(动态点分治+线段树)

    和[BZOJ3730]震波几乎一样,每个点建两棵线段树分别代表它的管辖范围内以它为LCA的路径的贡献和它对父亲的贡献. 注意点分树上的点的距离在原树上不单调,所以不能有若距离超出限制就break之类的 ...

  4. BZOJ4372: 烁烁的游戏(动态点分治)

    Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮 ...

  5. 【BZOJ4372】烁烁的游戏 动态树分治+线段树

    [BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...

  6. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...

  7. bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树

    [Submit][Status][Discuss] Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳 ...

  8. bzoj 4372 烁烁的游戏——动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372 和 bzoj 3070 震波 是一个套路.注意区间修改的话,树状数组不能表示 dis ...

  9. bzoj 4372 烁烁的游戏 —— 动态点分治+树状数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4372 本以为和 bzoj3730 一样,可以直接双倍经验了: 但要注意一下,树状数组不能查询 ...

  10. BZOJ4372: 烁烁的游戏【动态点分治】

    Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠. 题意: 给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠. 烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w ...

随机推荐

  1. 017 Java中的静态代理、JDK动态代理、cglib动态代理

    一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...

  2. golang验证提交的数据中某个字段是否重复

    提交的json数据如下: { , , , ", , , "screen_mode": "3,2", , "ad_plats":[ ...

  3. PH日期格式化

    %M 月名字(January--December) %W 星期名字(Sunday--Saturday) %D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等.) %Y 年, 数字, 4 位 ...

  4. Mac下PyCharm快捷键大全

    Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...

  5. 【学习笔记】Spring JdbcTemplate (3-3-3)

    Spring与JDBC模板(jdbcTemplate) 为了避免直接使用JDBC而带来的复杂冗长的代码 Spring提供的一个强有力的模板类 -- jdbcTemplate简化JDBC操作 并且数据源 ...

  6. js使用defineProperty的一些坑

    var p2={ }; Object.defineProperty(p2,"gs",{ get:function () { return this.gs; }, set:funct ...

  7. nyoj940 A dp problem 打表

    首先枚举i,那么构成i^2的最小值为1个正方形,当然1~1000并不会都得到答案,那么剩下的数字就递增枚举这些数,这个数可能右多对数构成,则枚举这些数.例如 5 = 1 + 4, 5 = 2 + 3, ...

  8. Redis安装,主从,主备切换

    网络环境: 主:10.187.120.5 从:10.187.69.58 从:10.187.69.59 一.安装 mv redis-2.8.19.tar.gz /export/servers/ cd / ...

  9. Effective Java 第三版——34. 使用枚举类型替代整型常量

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  10. C语言结构体定义的几种方法

    什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类.结构体可以被声明为变量.指针或数组等,用以实现较复杂的数据 ...