当前位置: 首页 > news >正文

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

题目描述

如题,已知一棵包含 NNN 个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:

  • 1 x y z,表示将树从 xxxyyy 结点最短路径上所有节点的值都加上 zzz

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

  • 3 x z,表示将以 xxx 为根节点的子树内所有节点值都加上 zzz

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

输入格式

第一行包含 444 个正整数 N,M,R,PN,M,R,PN,M,R,P,分别表示树的结点个数、操作个数、根节点序号和取模数(即所有的输出结果均对此取模)。

接下来一行包含 NNN 个非负整数,分别依次表示各个节点上初始的数值。

接下来 N−1N-1N1 行每行包含两个整数 x,yx,yx,y,表示点 xxx 和点 yyy 之间连有一条边(保证无环且连通)。

接下来 MMM 行每行包含若干个正整数,每行表示一个操作。

输出格式

输出包含若干行,分别依次表示每个操作 222 或操作 444 所得的结果(PPP 取模)。

输入输出样例 #1

输入 #1

5 5 2 24
7 3 7 8 0 
1 2
1 5
3 1
4 1
3 4 2
3 2 2
4 5
1 5 1 3
2 1 3

输出 #1

2
21

说明/提示

【数据规模】

对于 30%30\%30% 的数据: 1≤N≤101 \leq N \leq 101N101≤M≤101 \leq M \leq 101M10

对于 70%70\%70% 的数据: 1≤N≤1031 \leq N \leq {10}^31N1031≤M≤1031 \leq M \leq {10}^31M103

对于 100%100\%100% 的数据: 1≤N≤1051\le N \leq {10}^51N1051≤M≤1051\le M \leq {10}^51M1051≤R≤N1\le R\le N1RN1≤P≤2301\le P \le 2^{30}1P230。所有输入的数均在 int 范围内。

【样例说明】

树的结构如下:

各个操作如下:

故输出应依次为 222212121

题解

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
typedef long long ll;
int mod;
int n,m,r;
int a[N];
int sz[N],seg[N];
int son[N],top[N],dfn[N],deep[N],fa[N];
ll addTag[N<<2];
int cnt = 0;
ll sum[N<<2];
vector<int>e[N];void dfs(int u,int f)
{fa[u]=f;deep[u]=deep[f]+1;sz[u]=1;for(auto v:e[u]){if(v==f)continue;dfs(v,u);sz[u]+=sz[v];if(son[u]==0||sz[v]>sz[son[u]]){son[u]=v;}}
}void dfs2(int u,int f)
{top[u]=f;dfn[u]=++cnt;seg[cnt]=u;if(son[u]==0)return;dfs2(son[u],f);for(auto v:e[u]){if(v==fa[u]||v==son[u])continue;dfs2(v,v);}
}void up(int i)
{sum[i]=(sum[i<<1]+sum[i<<1|1])%mod;}void lazy(int i,ll v,int n)
{sum[i]=(sum[i]+v*n)%mod;addTag[i] = (addTag[i]+v)%mod;
}void down(int i,int ln,int rn)
{if(addTag[i]!=0){lazy(i<<1,addTag[i],ln);lazy(i<<1|1,addTag[i],rn);addTag[i]=0;}
}void build(int l,int r,int i)
{if(l==r){sum[i]=a[seg[l]]%mod;}else {int mid = (l+r)>>1;build(l,mid,i<<1);build(mid+1,r,i<<1|1);up(i);}
}void add(int jobl,int jobr,int v,int l,int r,int i)
{if(jobl<=l&&jobr>=r){lazy(i,v,r-l+1);}else {int mid = (l+r)>>1;down(i,mid-l+1,r-mid);if(mid>=jobl){add(jobl,jobr,v,l,mid,i<<1);}if(jobr>mid){add(jobl,jobr,v,mid+1,r,i<<1|1);}up(i);}
}ll query(int jobl,int jobr,int l,int r,int i)
{if(jobl<=l&&jobr>=r){return sum[i];}int mid = (l+r)>>1;down(i,mid-l+1,r-mid);ll ans = 0;if(jobl<=mid){ans = (ans+query(jobl,jobr,l,mid,i<<1))%mod;}if(jobr>mid){ans = (ans+query(jobl,jobr,mid+1,r,i<<1|1))%mod;}return ans;
}void pathAdd(int x,int y,int v)
{while(top[x]!=top[y]){if(deep[top[x]]<=deep[top[y]]){add(dfn[top[y]],dfn[y],v,1,n,1);y = fa[top[y]];}else {add(dfn[top[x]],dfn[x],v,1,n,1);x = fa[top[x]];}}add(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),v,1,n,1);
}void subtreeAdd(int x,int v)
{add(dfn[x],dfn[x]+sz[x]-1,v,1,n,1);}ll pathSum(int x,int y)
{ll ans = 0;while(top[x]!=top[y]){if(deep[top[x]]<=deep[top[y]]){ans=(query(dfn[top[y]],dfn[y],1,n,1)+ans)%mod;y = fa[top[y]];}else {ans = (ans+query(dfn[top[x]],dfn[x],1,n,1))%mod;x = fa[top[x]];}}ans = (ans+query(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,n,1))%mod;return ans;
}ll subtreeSum(int x)
{return query(dfn[x],dfn[x]+sz[x]-1,1,n,1);
}void solve()
{cin>>n>>m>>r>>mod;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<n;i++){int u,v;cin>>u>>v;e[u].push_back(v);e[v].push_back(u);}dfs(r,0);dfs2(r,r);build(1,n,1);for(int i=1;i<=m;i++){int opt;cin>>opt;if(opt==1){int x,y,z;cin>>x>>y>>z;pathAdd(x,y,z);}else if(opt==2){int x,y;cin>>x>>y;ll res = pathSum(x,y);cout<<res<<endl;}else if(opt==3){int x,z;cin>>x>>z;subtreeAdd(x,z);}else{int x;cin>>x;ll res = subtreeSum(x);cout<<res<<endl;}}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;// cin>>t;while(t--){solve();}return 0;
}
http://www.dtcms.com/a/577899.html

相关文章:

  • OpenCV(二十):位运算
  • 重组蛋白纯化标签科普:从His到SUMO、Avi的全面解析
  • 【QT第三章】常用控件1
  • 鱼台做网站多少钱wordpress 防黑
  • 南通网站建设排名公司网站怎么做图片放映效果
  • AI Agent:突破工作流局限,开启智能决策新时代
  • 自己动手写深度学习框架(神经网络的引入)
  • 西安专业网站建设服务好查询食品注册商标查询官网
  • ref对比reactive
  • 基于融智学双重形式化的汉字汉语数学建模方法
  • 手机wap网站多少钱wordpress页面简码
  • 嘉兴网嘉兴网站建设网址大全汽车之家官方网
  • 基于单片机的智能高温消毒与烘干系统设计
  • vue.js设计与实现(待续)
  • 2025 Vue UI 组件库选型
  • 网站内置字体法治网站的建设整改措施
  • 杭州高端网站设计南宁伯才网络建站如何
  • 面试题001
  • 【C#】NLog配置同时写入网络共享路径与本地路径日志
  • 用通俗易懂 + Android 开发实战的方式,详细讲解 Kotlin Flow 中的 retryWhen 操作符
  • Android 四大组件——BroadcastReceiver(广播)
  • 好看的单页面网站模板免费下载百度知道怎么赚钱
  • HTTP与HTTPS的核心区别及加密流程全解析:从明文传输到安全通信的演进
  • 好大夫王建设在线个人网站第一推广网
  • QML学习笔记(五十三)QML与C++交互:数据转换——序列类型与 JavaScript 数组的转换
  • Spring AI Alibaba语音合成实战:从零开始实现文本转语音功能
  • 科技向善,让养老更有温度——智慧养老的痛点破局与趋势前瞻
  • flink开发遇到的问题
  • “IP 地址” 咋分类?用 “电话号码分区” 讲透 A/B/C 类地址​
  • 网站建站服务公司网站建设和续费