[Submit][Status][Discuss]

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节点的皮皮鼠数量。

和震波拿到题十分相似,具体做法参考一下震波

Code:

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 6011111
#define N 500010
#define inf 0x7f7f7f
using namespace std;
int hd[N],nx[N],to[N],cnt;
int n,m,val[N],vis[N];
void add(int u,int v)
{nx[++cnt]=hd[u],hd[u]=cnt,to[cnt]=v;
}
namespace heavyedge{int dep[N],hson[N],fa[N],siz[N],top[N]; void dfs1(int u,int ff){dep[u]=dep[ff]+1,fa[u]=ff,siz[u]=1;           for(int i=hd[u];i;i=nx[i]) if(to[i]!=ff) {dfs1(to[i],u),siz[u]+=siz[to[i]];if(siz[to[i]]>siz[hson[u]]) hson[u]=to[i]; }}void dfs2(int u,int tp)    {   top[u]=tp; if(hson[u]) dfs2(hson[u],tp); for(int i=hd[u];i;i=nx[i]){if(to[i]==fa[u]||to[i]==hson[u]) continue; dfs2(to[i],to[i]); }}int LCA(int u,int v){while(top[u]!=top[v]) dep[top[u]] < dep[top[v]] ? v = fa[top[v]] : u = fa[top[u]];  return dep[u] < dep[v] ? u : v; }int main(){dfs1(1,0), dfs2(1,1); return 0; }
};
int Dis(int u,int v)
{  return heavyedge::dep[u] + heavyedge::dep[v] - (heavyedge::dep[heavyedge::LCA(u,v)] << 1);
}
int siz[N],f[N],root,sn,Fa[N];
int GetRoot(int u,int ff)
{siz[u] = 1,f[u] = 0; for(int i = hd[u]; i ; i = nx[i]) {if(to[i] == ff || vis[to[i]]) continue; GetRoot(to[i],u);     siz[u] += siz[to[i]]; f[u] = max(f[u],siz[to[i]]); }f[u] = max(f[u],sn - siz[u]); if(f[u] < f[root]) root = u;
}
void dfs(int u)
{vis[u] = 1; for(int i = hd[u]; i ; i = nx[i]){if(vis[to[i]]) continue; root = 0, sn = siz[to[i]], GetRoot(to[i],u);  Fa[root] = u, dfs(root); }
}
struct Segment_Tree{#define ls (t[o].l)#define rs (t[o].r) int tot; struct Node{int l,r,v; }t[maxn<<1]; void update(int &o,int l,int r,int p,int w){if(!o) o = ++cnt; t[o].v += w; if(l == r) return; int mid = (l + r) >> 1;if(p <= mid) update(t[o].l,l,mid,p,w); else update(t[o].r,mid + 1,r,p,w); }int query(int o,int l,int r,int L,int R){if(!o || l > r) return 0;if(l >= L && r <= R) return t[o].v; int mid = (l + r) >> 1,res = 0;   if(L <= mid) res += query(t[o].l,l,mid,L,R);if(R >= mid + 1) res += query(t[o].r,mid + 1,r, L,R); return res; }
}T;
int ans = 0,rt[N];
#define fax(x) (x + n)
void Update(int x,int k,int w)
{T.update(rt[x],0,n,0,w),T.update(rt[x],0,n,k + 1,-w);         for(int i = x; Fa[i]; i = Fa[i])         {int dis = Dis(x, Fa[i]);   if(k - dis < 0) continue; T.update(rt[Fa[i]],0,n,0,w),T.update(rt[Fa[i]],0,n,k - dis + 1,-w); T.update(rt[fax(i)],0,n,0,w),T.update(rt[fax(i)],0,n,k - dis + 1,-w); }
}
int Query(int x)
{int res = T.query(rt[x],0,n,0,0); for(int i = x; Fa[i] ; i = Fa[i]) {int dis = Dis(x, Fa[i]); res += T.query(rt[Fa[i]],0,n,0,dis); res -= T.query(rt[fax(i)],0,n,0,dis); }      return res;
}
char str[20];
int main()
{        // setIO("input"); scanf("%d%d",&n,&m);for(int i = 1,u,v;i < n; ++i)  scanf("%d%d",&u,&v), add(u,v),add(v,u); heavyedge :: main();       f[0] = inf, sn = n,root = 0,GetRoot(1,0), dfs(root);       while(m--){int x,y,z; scanf("%s",str);       if(str[0] == 'M') scanf("%d%d%d",&x,&y,&z),Update(x,y,z);    if(str[0] == 'Q') scanf("%d",&x), printf("%d\n",Query(x)); }      return 0;
}

  

转载于:https://www.cnblogs.com/guangheli/p/10921268.html

bzoj 4372: 烁烁的游戏 动态点分治_树链剖分_线段树相关推荐

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

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

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

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

  3. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

  4. BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)

    毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...

  5. BZOJ 4732 UOJ #268 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

  6. UOJ #268 BZOJ 4732 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

  7. BZOJ 3779 重组病毒 LCT,树链剖分,线段树

    题意: 给一棵树,每个点一开始颜色互不相同,支持三个操作                 1. 将一个点到根的路径染成一种新的颜色                 2. 将一个新的点设为根,并将原来的 ...

  8. bzoj 4372 烁烁的游戏 - 点分治 - 线段树

    动态点分治裸题 #include<iostream> #include<cstring> #include<cstdio> #include<map> ...

  9. BZOJ 4372 烁烁的游戏

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

最新文章

  1. 【统计学习方法】朴素贝叶斯对鸢尾花(iris)数据集进行训练预测
  2. LeetCode 1119. Remove Vowels from a String--C++,Java,Python解法
  3. io在Linux,在Linux进行IO的正确姿势
  4. 企业库应用实践系列三:自定义构造函数
  5. java中值传递机制
  6. 卡片的sak为不支持的类型_“师傅”两字是不能随便叫的!78%的网友不支持称顺风车主为“师傅”...
  7. Qt中的QFileDialog
  8. Java知识系统回顾整理01基础04操作符05赋值操作符
  9. [Training Video - 1] [Selenium Basics] [Download and Install Selenium]
  10. Redis 中的过期元素是如何被处理的?「视频版」——面试突击 002 期
  11. mysql事物及事物等级_MySQL事物原理及事务隔离级别
  12. cocos2dx打飞机项目笔记三:HeroLayer类和坐标系
  13. Cocoapods应用(001-简介以及安装和卸载)
  14. NLP基础—1.NLP概述
  15. 蓝桥杯2018年第九届C/C++省赛B组第二题-明码
  16. BZOJ 1857: [Scoi2010]传送带
  17. 更新的ccna实训交换机基本配置(附图)
  18. mysql导出成execl
  19. Apabi Reader 4.0.1正式发布!
  20. 使用SmartUpload的步骤

热门文章

  1. 查看linux4222端口,linux 内核 ALIGN 含义
  2. python阶乘匿名函数_python的高阶函数与匿名函数
  3. python怎么装饰_如何理解python装饰器
  4. 全局变量中断原子操作_中断函数里改变一个全局变量的值,在主函数里却检测到未变化...
  5. vscode打造golang开发环境以及golang的debug单元测试
  6. python【数据结构与算法】动态规划模版
  7. python【蓝桥杯vip练习题库】ALGO-50 数组查找及替换
  8. Android之Pull解析XML
  9. [BZOJ 2523][Ctsc2001]聪明的学生(递归)
  10. R语言中的esttab命令_R语言︱基本函数、统计量、常用操作函数