正题

题目链接:https://www.luogu.com.cn/problem/P6329


解题思路

给出nnn个点的一棵树,每个点有权值,有mmm次操作

  1. 修改一个点xxx的权值为yyy
  2. 询问距离点xxx不超过kkk的所有点点权和

解题思路

点分树的模板题,先点分治构造出点分树,然后在上面维护信息。

对于每个点维护一个点分子树内,与该点的距离为下标,点权为权值的的树状数组,然后查询的时候直接查距离不超过k−dis(now,x)k-dis(now,x)k−dis(now,x)的就好了。

发现与点分父节点会有算重的情况,这个时候顺便维护一个以与父节点的距离为下标的树状数组,然后减去重复的答案就好了。

时间复杂度O(nlog⁡2n)O(n\log^2 n)O(nlog2n)。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lowbit(x) (x&-x)
using namespace std;
const int N=1e5+10,T=18,inf=1e9;
struct node{int to,next;
}a[N<<1];
int n,m,tot,cnt,num,root,fr,val[N];
int ls[N],f[N<<1][T],rfn[N],dep[N];
int fa[N],siz[N],lg[N<<1],mx;
bool v[N];
struct BIT{vector<int> t;int n;void Init(int x){x++;t.resize(x);n=x;return;}void Change(int x,int val){x++;while(x<=n){t[x-1]+=val;x+=lowbit(x);}return;}int Ask(int x){if(x<0)return 0;int ans=0;x++;if(x>n)x=n;while(x){ans+=t[x-1];x-=lowbit(x);}return ans;}
}s1[N],s2[N];
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
void dfs(int x,int fa){dep[x]=dep[fa]+1;f[++cnt][0]=x;rfn[x]=cnt;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;dfs(y,x);f[++cnt][0]=x;}return;
}
void groot(int x,int fa){siz[x]=1;int f=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(v[y]||y==fa)continue;groot(y,x);siz[x]+=siz[y];f=max(f,siz[y]);}f=max(f,num-siz[x]);if(f<fr)root=x,fr=f;return;
}
void calc(int x,int fa,int dep){mx=max(mx,dep);for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa||v[y])continue;calc(y,x,dep+1);}return;
}
void Build(int x,int h){v[x]=1;int S=num,z=fr;mx=0;calc(x,x,0);s1[x].Init(mx);s2[x].Init(h);for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(v[y])continue;num=(siz[y]>siz[x])?(S-siz[x]):siz[y];mx=0;calc(y,x,1);fr=inf;groot(y,x);y=root;fa[y]=x;Build(y,mx);}return;
}
void Init(){dfs(1,1);for(int i=2;i<=cnt;i++)lg[i]=lg[i>>1]+1;for(int j=1;(1<<j)<=cnt;j++)for(int i=1;i+(1<<j)-1<=cnt;i++){int x=f[i][j-1],y=f[i+(1<<j-1)][j-1];f[i][j]=(dep[x]<dep[y])?x:y;}fr=inf;num=n;groot(1,1);Build(root,0);return;
}
int LCA(int l,int r){l=rfn[l];r=rfn[r];if(l>r)swap(l,r);int z=lg[r-l+1];int x=f[l][z],y=f[r-(1<<z)+1][z];return (dep[x]<dep[y])?x:y;
}
int dis(int x,int y)
{return dep[x]+dep[y]-2*dep[LCA(x,y)];}
void Updata(int x,int val){int now=x;while(now){s1[now].Change(dis(now,x),val);if(fa[now])s2[now].Change(dis(fa[now],x),val);now=fa[now];}return;
}
int Ask(int x,int k){int ans=0,now=x;ans=s1[x].Ask(k);while(fa[now]){int d=dis(fa[now],x);ans+=s1[fa[now]].Ask(k-d);if(fa[now])ans-=s2[now].Ask(k-d);now=fa[now];}return ans;
}
int main()
{// freopen("P6329_1.in","r",stdin);// freopen("data.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&val[i]);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}Init();for(int i=1;i<=n;i++)Updata(i,val[i]);int last=0;while(m--){int op,x,y;scanf("%d%d%d",&op,&x,&y);x^=last;y^=last;if(op){Updata(x,y-val[x]);val[x]=y;}elseprintf("%d\n",last=Ask(x,y));}return 0;
}

P6329-[模板]点分树 | 震波相关推荐

  1. P6329 【模板】点分树 | 震波

    P6329 [模板]点分树 | 震波 这是一道模板题,需要支持两个操作,操作一就是单点修改点权,操作二就是查询距离x不超过k的点权值和. 我们考虑建出点分树,然后对于每个点维护两个数据结构,一个处理当 ...

  2. 洛谷·【模板】点分树 | 震波【including 点分树

    初见安-这里是传送门:洛谷P6329 [模板]点分树 | 震波 一.点分树 其实你会点分治的话,点分树就是把点分治时的重心提出来重新连城一棵树. 比如当前点是u,求出子树v的重心root后将root与 ...

  3. luogu P6329 【模板】点分树 | 震波

    https://www.luogu.com.cn/problem/P6329 先建一颗点分树 考虑树上的每个节点维护什么 因为树高是log的,所以怎么暴力怎么维护就好了 维护两个前缀和, u u u的 ...

  4. 线段树练习 3P3372 【模板】线段树 1

    题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...

  5. P3373 【模板】线段树 2

    P3373 [模板]线段树 2 相对于线段树模板1有了区间乘的操作,所以增加了一个乘的延迟标记,当加和乘的次序不同的时候,我们要好好考虑这两个延迟标记对孩子的影响.所以这里我们是采取的是先乘后加. 线 ...

  6. 【洛谷3345_BZOJ3924】[ZJOI2015]幻想乡战略游戏(点分树)

    大概有整整一个月没更博客了 -- 4 月为省选爆肝了一个月,最后压线进 B 队,也算给 NOIP2018 翻车到 316 分压线省一这个折磨了五个月的 debuff 画上了一个不算太差的句号.结果省选 ...

  7. P3373 【模板】线段树 2 (未完待续)

    P3373 [模板]线段树 2 强烈安利这个大佬 超赞!!! 题解 本来以为这个题拿着线段树1的板子改改就好了,但是发现事情并没有那么简单,改了两天... 我们看到这个题其实涉及啦乘法和加法两种运算, ...

  8. [Codeforces757G]Can Bash Save the Day?——动态点分治(可持久化点分树)

    题目链接: Codeforces757G 题目大意:给出一棵n个点的树及一个1~n的排列pi,边有边权,有q次操作: 1 l r x 求 $\sum\limits_{i=l}^{r}dis(p_{i} ...

  9. BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

最新文章

  1. @OneToMany
  2. FreeTextBox 3.1.6 的实践总结
  3. 判断ipad还是安卓_?谷歌认输,iPad或成唯一赢家,安卓平板路在何方?
  4. JVM 内存示意图(内存结构图/内存解析图)
  5. mysql主键long_MySQL主键设计
  6. QT的常用对话框的应用
  7. 记录sqoop同步失败问题解决过程,过程真的是很崎岖。(1月6日解决)
  8. netsuite中Mutiple Select的赋值问题的解决
  9. java 数字 下划线_数字文字中的下划线– Java 7功能
  10. 51单片机硬件基础知识
  11. ppa什么网_ppa网站-和ppa网站相关的内容-阿里云开发者社区
  12. 互联网日报 | 微信聊天上线“超链接”功能;B站月付费用户达1500万;优客工场正式登陆纳斯达克...
  13. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explo注册表病毒
  14. R语言绘制山脊图 ggridge,如何给每个山脊添加自定义垂直线?
  15. (39.1)【XML漏洞专题】必备的基础知识、利用原理、构建规则
  16. PostgreSQL 时序数据案例 - 时间流逝, 自动压缩, 同比\环比
  17. jenkins忘记管理员密码修改
  18. python strip 函数用法及介绍
  19. [自动驾驶系列一]Introduction to Self-Driving Cars
  20. 获取日历的法定节假日

热门文章

  1. 创建失败_号称人人都可编辑的百科词条,创建之路为何屡屡失败?
  2. java hdms_字段为clob类型,无法插入数据
  3. css伪类元素加在元素前,CSS伪类:before在元素之前 :after 在元素之后实例讲解
  4. localhost 已拒绝连接_MySQL连接错误:Access denied for #x27;root#x27;@#x27;localhost#x27;
  5. mybatis mysql usegeneratedkeys_mybatis中useGeneratedKeys用法--插入数据库后获取主键值
  6. maya的颤动怎么做_必看!新手学习MAYA的几个建议
  7. linux开发板推荐_【新品发布】WiFi开发板XW-01-Kit,超低功耗,冷启快联,智能门锁首选!...
  8. java转python推荐算法_java和python实现一个加权SlopeOne推荐算法
  9. 二分法——leetcode35. 搜索插入位置
  10. leetcode112. 路径总和