首页 > 其他分享 >2022.10.26

2022.10.26

时间:2024-10-22 14:22:52浏览次数:1  
标签:26 ch 树剖 LL 节点 && 2022.10 id

树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!树剖!

练习情况:

P3384 【模板】轻重链剖分/树链剖分

P3178 [HAOI2015]树上操作

P2590 [ZJOI2008]树的统计

P3833 [SHOI2012]魔法树

P2146 [NOI2015] 软件包管理器

P4427 [BJOI2018]求和

P3258 [JLOI2014]松鼠的新家

P3128 [USACO15DEC]Max Flow P

P6098 [USACO19FEB]Cow Land G

以上都是维护节点的树剖,本质都是一个东西。

树剖

将整颗树,剖分成轻重链,再用数据结构维护。

操作主要是

  • 1 x y z,表示将树从 \(x\) 到 \(y\) 结点最短路径上所有节点的值都加上 \(z\)。

  • 2 x y,表示求树从 \(x\) 到 \(y\) 结点最短路径上所有节点的值之和。

  • 3 x z,表示将以 \(x\) 为根节点的子树内所有节点值都加上 \(z\)。

  • 4 x 表示求以 \(x\) 为根节点的子树内所有节点值之和。

数据结构维护的一般是节点的 dfs 序。

对于最短路径上的操作,我们要用类似 LCA 的方法跳链,对路径上的链进行操作。

对于子树的操作,因为 dfs 序是连续的,所以可以直接进行维护。

Code:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define Ld long double
#define l(p) tree[p].l
#define r(p) tree[p].r
#define sum(p) tree[p].sum
#define add(p) tree[p].add
const int N = 100005,M=100005;

LL n,m,r,mod,a[N];
LL head[N],net[M*2],val[M*2],idx=1;
LL f[N],d[N],son[N],id[N],siz[N],rk[N],tp[N],cnt;
LL op,x,y,z;
struct Segment_tree{
    LL sum,add,l,r;
}tree[N*4];

inline char readc(){
    char ch=getchar();
    while(!((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))) ch=getchar();
    return ch;
}
inline LL read(){
    LL s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
    return s*w;
}
inline void print(LL x){
    char F[200];LL cnt=0;
    if(x==0){putchar('0');putchar('\n');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){F[++cnt]=x%10;x/=10;}
    while(cnt) putchar(F[cnt--]+'0');
    putchar('\n');return ;
}

void add1(LL x,LL y){
    val[++idx]=y;
    net[idx]=head[x];
    head[x]=idx;
    return ;
}

void dfs1(LL u,LL fa){
    f[u]=fa,d[u]=d[fa]+1,siz[u]=1;
    for(int i=head[u];i;i=net[i]){
        LL v=val[i];
        if(v==fa) continue;
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]])
            son[u]=v;
    }
    return ;
}

void dfs2(LL u,LL top){
    tp[u]=top,id[u]=++cnt,rk[cnt]=u;
    if(son[u]) dfs2(son[u],top);
    for(int i=head[u];i;i=net[i]){
        LL v=val[i];
        if(v!=f[u]&&v!=son[u])
        dfs2(v,v);
    }
    return ;
}

void pushup(LL p){
    sum(p)=(sum(p<<1)+sum(p<<1|1))%mod;
    return ;
}

void pushdown(LL p){
    if(!add(p)) return ;
    add(p<<1)=(add(p<<1)+add(p))%mod;
    add(p<<1|1)=(add(p<<1|1)+add(p))%mod;
    sum(p<<1)=(sum(p<<1)+add(p)*(r(p<<1)-l(p<<1)+1))%mod;
    sum(p<<1|1)=(sum(p<<1|1)+add(p)*(r(p<<1|1)-l(p<<1|1)+1))%mod;
    add(p)=0;
    return ;

}

void build(LL p,LL l,LL r){
    l(p)=l,r(p)=r;
    if(l==r){
        sum(p)=a[rk[l]];
        return ;
    }
    LL mid=(l(p)+r(p))>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}

void change2(LL p,LL l,LL r,LL k){
    if(l(p)>=l&&r(p)<=r){
        add(p)=(add(p)+k)%mod;
        sum(p)=(sum(p)+k*(r(p)-l(p)+1))%mod;
        return ;
    }
    pushdown(p);
    LL mid=(l(p)+r(p))>>1;
    if(l<=mid) change2(p<<1,l,r,k);
    if(r>mid) change2(p<<1|1,l,r,k);
    pushup(p);
    return ;
}

void change1(LL p,LL l,LL r,LL k){
    while(tp[l]!=tp[r]){
        if(d[tp[l]]<d[tp[r]]) swap(l,r);
        change2(1,id[tp[l]],id[l],k);
        l=f[tp[l]];
    }
    if(id[l]>id[r]) swap(l,r);
    change2(1,id[l],id[r],k);
    return ;
}

LL query2(LL p,LL l,LL r){
    if(l(p)>=l&&r(p)<=r) return sum(p);
    pushdown(p);
    LL mid=(l(p)+r(p))>>1,val=0;
    if(l<=mid) val+=query2(p<<1,l,r);
    if(r>mid) val+=query2(p<<1|1,l,r);
    return val%mod;
}

LL query1(LL p,LL l,LL r){
    LL val=0;
    while(tp[l]!=tp[r]){
        if(d[tp[l]]<d[tp[r]]) swap(l,r);
        val=(val+query2(1,id[tp[l]],id[l]))%mod;
        l=f[tp[l]];
    }
    if(id[l]>id[r]) swap(l,r);
    return (val+query2(1,id[l],id[r]))%mod;
}

int main(){
    n=read(),m=read(),r=read(),mod=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(LL i=1,u,v;i<n;i++){
        u=read(),v=read();
        add1(u,v);
        add1(v,u);
    }
    dfs1(r,0);
    dfs2(r,r);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        op=read(),x=read();
        if(op==1){
            y=read(),z=read();
            change1(1,x,y,z);
        }else
        if(op==2){
            y=read();
            print(query1(1,x,y));
        }else
        if(op==3){
            z=read();
            change2(1,id[x],id[x]+siz[x]-1,z);
        }else
        if(op==4){
            print(query2(1,id[x],id[x]+siz[x]-1));
        }
    }
    return 0;
}

P4114 Qtree1

P4315 月下“毛景树”

P3038 [USACO11DEC]Grass Planting G

以上是维护边的树剖。

这个相对于维护点的树剖只有一点点差别。

我们将每条边的权值赋给边两端深度较大的那个节点。

差别

在两点之间维护时

if(id[l]>id[r]) swap(l,r);
    return max(val,query2(1,id[l]+1,id[r]));

id[l] 为 LCA 这个节点的权值不包含在要维护的边内,所以要加 1 。

Code:

P4315


一天写了挺多树剖的,但这些都感觉长的差不多,只是把序列拍在树上,增加1kb码量

那么将线段树的题目搞到树上是不是就是一道新的树剖。

标签:26,ch,树剖,LL,节点,&&,2022.10,id
From: https://www.cnblogs.com/xingke233/p/18492627

相关文章

  • 2022.10.27
    CSP-S寄了,被COVID-19定点打击。练习情况P1402酒店之王P1231教辅的组成P2891[USACO07OPEN]DiningG最大流,关键在建图,以P1402为例。一开始我是这样建的。源点->房间->客人->菜品->汇点看起来没有问题,但实际上这有很大问题。如:这样的图,一个人就贡献了2次......
  • 2022.10.20
    练习情况P3601签到题有意思的题目,先筛出\(10^6\)的质数,每个质数对\(l\)~\(r\)的贡献。每个质数在\(l\)~\(r\)下界是\((\dfrac{(l-1)}{P}+1)P\)可以用分块思想理解Code:for(LLi=1;prime[i]*prime[i]<=r;i++){for(LLj=((l-1)/prime[i]+1)*prime[i];j<=......
  • 2022.10.17
    练习情况P1040[NOIP2003提高组]加分二叉树区间dp,枚举区间加子树的根并记录。Code:P1040P4933大师\(O(n^2)\)的dp,枚举在\(i\)之前的\(j\)与其的公差。公差为负的情况,将所有公差加上一个正数。Code:P4933P2832行路难一眼最短路,结果假了。正解\(BFS\)加......
  • 知识分享 | 符合ISO 26262标准的工具分类与鉴定
    作者:Prof.Dr.MirkoConrad,SophiaKohle&Dr.HartmutPohlheim 软件工具被广泛应用于促进安全相关电子/电器系统的开发之中。这些工具通过自动化所执行的活动,并通过可预测的方式执行容易出现人为失误的操作,从而潜在地提高安全性。与之相反,如果工具执行其预定功能不充分......
  • Springboot计算机毕业设计程序设计竞赛团队管理系统72262
    Springboot计算机毕业设计程本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:团队信息,用户,团队风采,团队成员,团队项目,项目反馈,团队任务开题报告内容一、研究背景与意义随着信息技术的飞速发展......
  • 1126. 查询活跃业务
    力扣题目跳转(1126.查询活跃业务-力扣(LeetCode))事件表:Events+---------------+---------+|ColumnName|Type|+---------------+---------+|business_id|int||event_type|varchar||occurrences|int|+---------------+---------+......
  • ue4.26 niagara collisionNormal问题
    目的是让粒子片自由下落,与表面碰撞后停止并调整为与表面一致的朝向。测试用例搭建如下:1,建一个niageraSystem,直接用Fountain模板。2,确认EmitterProperties中SimTarget是CPUSim(出于兼容性考虑)2,在SolveForcesandVelocity前添加Collsion模块(CPU碰撞)。3,将Collision中的Fricti......
  • 微信小程序 php+uniapp医院预约挂号体检系统 0d26l
    目录项目介绍具体实现截图技术介绍设计方法和思路小程序框架以及目录结构介绍java类核心代码部分展示其他uniapp小程序题目推荐详细视频演示源码获取项目介绍系统是医院建设中不可缺少的基础设施与支撑环境,是中心的整体形象、档次和服务水准的有力表现方式。它需要......
  • Leetcode 1926. 迷宫中离入口最近的出口
    1.题目基本信息1.1.题目描述给你一个mxn的迷宫矩阵maze(下标从0开始),矩阵中有空格子(用‘.’表示)和墙(用‘+’表示)。同时给你迷宫的入口entrance,用entrance=[entrancerow,entrancecol]表示你一开始所在格子的行和列。每一步操作,你可以往上,下,左或者右移动一......
  • (附源码)基于python的旅游大数据系统的设计与实现-计算机毕设 26553
    基于python的旅游大数据系统的设计与实现目 录1绪论1.1选题背景和意义1.2国内外研究现状1.3论文结构与章节安排1.4开发技术1.4.1MVVM模式介绍1.4.2Django框架1.4.3Vue.js主要功能2 系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 操作可......