题外话

(其实模板题没必要在这里水题解的……主要是想说这个qwq)

小常数的快乐.jpg

我也不知道我为啥常数特别小跑得飞快……不加快读就能在 luogu 的最优解上跑到 rank5 (

说不定深夜提交个 fread 版本能上rk3

题目链接

题意

给定一棵带点权的树,边权为1,在线处理m次操作

  1. 0 x k 询问所有与 x 距离不超过 k 的点权和
  2. 1 x y 修改 x 的点权为 y

思路

首先建点分树。对于每个点维护两个树状数组,以距离为下标,权值为内容。第一个维护子树中距离该点为k的权值和,第二个维护父亲的内容(同第一个)。

对于修改操作,暴力爬树高,\(log^2\) 复杂度(树高加上树状数组)。

对于查询操作,一样爬树高,进行容斥(把当前子树 \(k\) 的先加起来,往祖先上爬,如果距离小于 \(k\) ,假设为 \(d\),到祖先上去求一个 \(k-d\),再容斥掉原来这棵子树里被计算过的)。

顺便,把最开始的建树当成 modify 能省很多事qwq

代码

#include <bits/stdc++.h>
#define lowbit(x) ((x)&(-x))
using namespace std;
const int N=1e5+10,inf=1e9+7;
struct edge
{
int to,nxt;
}e[N<<1];
int n,m,head[N],val[N],fa[N][20],dis[N][20],sz[N],f[N],dep[N],rt,siz,tot=0;
bool vis[N];
vector<int> sbit[N],fbit[N]; void add( int u,int v )
{
e[++tot]=(edge){v,head[u]}; head[u]=tot;
e[++tot]=(edge){u,head[v]}; head[v]=tot;
} void get_rt( int x,int fat )
{
sz[x]=1; f[x]=0;
for ( int i=head[x]; i; i=e[i].nxt )
{
int y=e[i].to;
if ( vis[y] || fat==y ) continue;
get_rt( y,x ); sz[x]+=sz[y]; f[x]=max( f[x],sz[y] );
}
f[x]=max( f[x],siz-sz[x] );
if ( f[x]<f[rt] ) rt=x;
} void pre_build( int x,int ancestor,int fat,int d )
{
for ( int i=head[x]; i; i=e[i].nxt )
{
int y=e[i].to;
if ( vis[y] || y==fat ) continue;
fa[y][++dep[y]]=ancestor; dis[y][dep[y]]=d;
pre_build( y,ancestor,x,d+1 );
}
} void build( int x )
{
vis[x]=1; pre_build( x,x,0,1 );
int sav=siz; sbit[x].resize( siz+1 ); fbit[x].resize( siz+1 );
for ( int i=head[x]; i; i=e[i].nxt )
{
int y=e[i].to; if ( vis[y] ) continue;
siz=sz[y]; if ( siz>sz[x] ) siz=sav-sz[x];
rt=0; get_rt( y,x ); build( rt );
}
} int qsum_s( int x,int k )
{
int res=val[x],lim=sbit[x].size()-1; k=min( k,lim );
for ( int i=k; i; i-=lowbit(i) ) res+=sbit[x][i];
return res;
} int qsum_f( int x,int k )
{
int res=0,lim=fbit[x].size()-1; k=min( k,lim );
for ( int i=k; i; i-=lowbit(i) ) res+=fbit[x][i];
return res;
} void modify( int x,int v )
{
int d=dis[x][dep[x]],lim=sbit[x].size()-1;
for ( int j=d; j<=lim && j; j+=lowbit(j) ) fbit[x][j]+=v;
for ( int i=dep[x]; i; i-- )
{
d=dis[x][i]; lim=sbit[fa[x][i]].size()-1;
for ( int j=d; j<=lim; j+=lowbit(j) ) sbit[fa[x][i]][j]+=v;
d=dis[x][i-1];
for ( int j=d; j<=lim && j; j+=lowbit(j) ) fbit[fa[x][i]][j]+=v;
}
} int query( int x,int k )
{
int res=qsum_s( x,k );
for ( int i=dep[x]; i; i-- )
if ( dis[x][i]<=k ) res+=qsum_s( fa[x][i],k-dis[x][i] )-qsum_f( fa[x][i+1],k-dis[x][i] );
return res;
} int main()
{
scanf( "%d%d",&n,&m );
for ( int i=1; i<=n; i++ )
scanf( "%d",&val[i] );
for ( int i=1,u,v; i<n; i++ )
scanf( "%d%d",&u,&v ),add( u,v ); f[0]=inf; siz=n; get_rt( 1,0 ); build( rt );
for ( int i=1; i<=n; i++ )
fa[i][dep[i]+1]=i;
for ( int i=1; i<=n; i++ )
modify( i,val[i] );
int las=0;
while ( m-- )
{
int opt,x,y; scanf( "%d%d%d",&opt,&x,&y );
x^=las; y^=las;
if ( opt==0 ) las=query( x,y ),printf( "%d\n",las );
else modify( x,y-val[x] ),val[x]=y;
}
}

【题解】P6329 【模板】点分树 | 震波的更多相关文章

  1. P6329-[模板]点分树 | 震波

    正题 题目链接:https://www.luogu.com.cn/problem/P6329 解题思路 给出\(n\)个点的一棵树,每个点有权值,有\(m\)次操作 修改一个点\(x\)的权值为\(y ...

  2. 【bzoj3435】[Wc2014]紫荆花之恋 替罪点分树套SBT

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

  3. 线段树学习笔记(基础&进阶)(一) | P3372 【模板】线段树 1 题解

    什么是线段树 线段树是一棵二叉树,每个结点存储需维护的信息,一般用于处理区间最值.区间和等问题. 线段树的用处 对编号连续的一些点进行修改或者统计操作,修改和统计的复杂度都是 O(log n). 基础 ...

  4. 题解 P3372 【【模板】线段树1 】(zkw)

    看了一下题解里的zkw线段树,感觉讲的不是很清楚啊(可能有清楚的但是我没翻到,望大佬勿怪). 决定自己写一篇...希望大家能看明白... zkw线段树是一种优秀的非递归线段树,速度比普通线段树快两道三 ...

  5. 题解 P3372 【【模板】线段树1 】

    看了一下题解里的zkw线段树,感觉讲的不是很清楚啊(可能有清楚的但是我没翻到,望大佬勿怪). 决定自己写一篇...希望大家能看明白... zkw线段树是一种优秀的非递归线段树,速度比普通线段树快两道三 ...

  6. 洛谷 P3373 【模板】线段树 2 题解

    P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入格式 第一行包含三个整数 ...

  7. 洛谷P3373 【模板】线段树 2 && P2023 [AHOI2009]维护序列——题解

    题目传送: P3373 [模板]线段树 2  P2023 [AHOI2009]维护序列 该题较传统线段树模板相比多了一个区间乘的操作.一提到线段树的区间维护问题,就自然想到了“懒标记”:为了降低时间复 ...

  8. 一篇自己都看不懂的点分治&点分树学习笔记

    淀粉质点分治可真是个好东西 Part A.点分治 众所周知,树上分治算法有$3$种:点分治.边分治.链分治(最后一个似乎就是树链剖分),它们名字的不同是由于分治方式的不同的.点分治,顾名思义,每一次选 ...

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

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

随机推荐

  1. 关于ThreadLocal的那些事

    这篇文章(看完了再看下面的)很好地解释了ThreadLocal是什么,怎么用,是否能解决线程安全问题,非常nice.但个人认为讲解存在遗漏,进行如下示例补充: InheritableThreadLoc ...

  2. string.contains()

    public class test { public static void main(String[] args){ System.out.println("abcde".con ...

  3. python之路《九》 迭代器与生成器

    1.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...

  4. Spring源码之循环依赖

    https://www.cnblogs.com/longy2012/articles/12834762.html https://www.bilibili.com/video/BV1iD4y1o7pM ...

  5. 一个List按照某个size分割为多个小的List

    针对于List的size比较大,使用多线程处理任务时,可以将List分割为一个一个比较小的任务单元进行处理. 例如集合大小:645,按照100分割,会将集合分割为6个size为100的集合和一个siz ...

  6. 面试BAT问的最多的27道MyBatis 面试题(含答案和思维导图总结)

    前言 关于MyBatis总结了一个思维导图希望对大家有帮助 什么是 Mybatis? Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身, ...

  7. 如何使Camtasia的抠像效果更真实自然

    相信大家都知道录像编辑软件Camtasia的"移除颜色"可以抠像换背景,详细操作可以看小编的另一篇教程 <如何用Camtasia为微课换上一个好看的背景>.接下来,小编 ...

  8. MongoDB集群分片部署

    MongoDB中使用分片集群结构分布: 三个主要组件: Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故 ...

  9. 模拟赛41 A. 四个质数的和

    题目描述 给定了一个正整数 \(N\).有多少种方法将 \(N\) 分解成为四个质数 \(a,b,c,d\)的和. 例如: \(9=2+2+2+3=2+2+3+2=2+3+2+2=3+2+2+2\), ...

  10. Pytest自动化测试 - 必知必会的一些插件

    Pytest拥有丰富的插件架构,超过800个以上的外部插件和活跃的社区,在PyPI项目中以" pytest- *"为标识. 本篇将列举github标星超过两百的一些插件进行实战演示 ...