「LuoguP3384」【模板】树链剖分
题目描述
如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:
操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z
操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和
操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z
操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和
输入输出格式
输入格式:
第一行包含4个正整数N、M、R、P,分别表示树的结点个数、操作个数、根节点序号和取模数(即所有的输出结果均对此取模)。
接下来一行包含N个非负整数,分别依次表示各个节点上初始的数值。
接下来N-1行每行包含两个整数x、y,表示点x和点y之间连有一条边(保证无环且连通)
接下来M行每行包含若干个正整数,每行表示一个操作,格式如下:
操作1: 1 x y z
操作2: 2 x y
操作3: 3 x z
操作4: 4 x
输出格式:
输出包含若干行,分别依次表示每个操作2或操作4所得的结果(对P取模)
输入输出样例
说明
时空限制:1s,128M
数据规模:
对于30%的数据: N≤10,M≤10
对于70%的数据: N≤10^3,M≤10^3
对于100%的数据: N≤10^5,M≤10^5
( 其实,纯随机生成的树LCA+暴力是能过的,可是,你觉得可能是纯随机的么233 )
样例说明:
树的结构如下:

各个操作如下:

故输出应依次为2、21(重要的事情说三遍:记得取模)
题解
我也是会树剖的女人了!!!嗷嗷嗷嗷嗷嗷嗷嗷嗷嗷
模板题嘛QAQ,也没什么好讲的
剖了之后,对于操作1和2,在求lca的过程中做
对于操作3和4,直接在dfn[x]和dfn[x]+siz[x]-1上搞事就星了
其实操作1和2可以用树上前缀和水水水水水水(不对要随时询问好像布星QAQ)
#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=2e5+;
int val[MAXN];//点权
//以下建原树
struct emm{
int e,f;
}b[*MAXN];
int h[MAXN];
int tot=;
void con(int x,int y)
{
b[++tot].f=h[x];
h[x]=tot;
b[tot].e=y;
b[++tot].f=h[y];
h[y]=tot;
b[tot].e=x;
return;
}
//第一遍dfs
int d[MAXN],fa[MAXN],top[MAXN],z[MAXN],siz[MAXN];
void dfs(int x)
{
siz[x]=;
top[x]=x;
int mac=,macc=-;
for(int i=h[x];i;i=b[i].f)
if(!d[b[i].e])
{
d[b[i].e]=d[x]+;
fa[b[i].e]=x;
dfs(b[i].e);
siz[x]+=siz[b[i].e];
if(macc<siz[b[i].e]){mac=b[i].e,macc=siz[b[i].e];}
}
z[x]=mac;
top[mac]=x;
return;
}
//第二遍dfs
int q[MAXN],dfn[MAXN];
void dfss(int x)
{
q[++tot]=x;
dfn[x]=tot;
if(z[x])dfss(z[x]);
for(int i=h[x];i;i=b[i].f)
if(fa[b[i].e]==x&&b[i].e!=z[x])
dfss(b[i].e);
return;
}
//找top
int fitop(int x)
{
if(top[x]==x)return x;
return top[x]=fitop(top[x]);
}
//建树完成
int n,m,s;
long long mod;
//以下线段树
struct ahh{
int l,r;
long long v,laz;
}a[*MAXN];
void build(int i,int ll,int rr)
{
a[i].l=ll;
a[i].r=rr;
if(ll==rr){a[i].v=val[q[ll]];return;}
int mid=(ll+rr)>>;
build((i<<),ll,mid);
build(((i<<)|),mid+,rr);
a[i].v=a[(i<<)].v+a[((i<<)|)].v%mod;
return;
}
void add(int i,int ll,int rr,int k)
{
if(a[i].l==ll&&a[i].r==rr)
{a[i].laz+=k;return;}
a[i].v=(long long)a[i].v+(rr-ll+)*k%mod;
int mid=(a[i].l+a[i].r)>>;
if(rr<=mid)add((i<<),ll,rr,k);
else if(mid+<=ll)add(((i<<)|),ll,rr,k);
else {add((i<<),ll,mid,k);add(((i<<)|),mid+,rr,k);}
return;
}
void pushtag(int i)
{
if(!a[i].laz)return;
a[i].v=(long long)a[i].v+a[i].laz*(a[i].r-a[i].l+)%mod;
if(a[i].l==a[i].r){a[i].laz=;return;}
a[(i<<)].laz+=a[i].laz;
a[((i<<)|)].laz+=a[i].laz;
a[i].laz=;
return;
}
unsigned long long ans;
void find(int i,int ll,int rr)
{
pushtag(i);
if(a[i].l==ll&&a[i].r==rr){ans=(ans+a[i].v)%mod;return;}
int mid=(a[i].l+a[i].r)>>;
if(rr<=mid)find((i<<),ll,rr);
else if(ll>=mid+)find(((i<<)|),ll,rr);
else {find((i<<),ll,mid);find(((i<<)|),mid+,rr);}
return;
}
//
int main()
{
//freopen("a.in","r",stdin);
scanf("%d%d%d%lld",&n,&m,&s,&mod);
for(int i=;i<=n;++i)
scanf("%d",&val[i]);
for(int i=;i<n;++i)
{
int x,y;
scanf("%d%d",&x,&y);
con(x,y);
}
d[s]=;
dfs(s);
tot=;
dfss(s);
for(int i=;i<=n;++i)
top[i]=fitop(i);
build(,,n);
//run
for(int c=;c<=m;++c)
{
int opt;
scanf("%d",&opt);
if(opt==)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
//lca
while(top[x]!=top[y])
{
if(d[top[x]]>d[top[y]])
{
add(,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
else
{
add(,dfn[top[y]],dfn[y],z);
y=fa[top[y]];
}
}
if(d[x]>d[y])add(,dfn[y],dfn[x],z);
else add(,dfn[x],dfn[y],z);
}
else if(opt==)
{
int x,y;
scanf("%d%d",&x,&y);
ans=;
while(top[x]!=top[y])
{
if(d[top[x]]>d[top[y]])
{
find(,dfn[top[x]],dfn[x]);
ans%=mod;
x=fa[top[x]];
}
else
{
find(,dfn[top[y]],dfn[y]);
ans%=mod;
y=fa[top[y]];
}
}
if(d[x]>d[y])find(,dfn[y],dfn[x]);
else find(,dfn[x],dfn[y]);
printf("%lld\n",ans%mod);
}
else if(opt==)
{
int x,z;
scanf("%d%d",&x,&z);
add(,dfn[x],dfn[x]+siz[x]-,z);
}
else
{
int x;
scanf("%d",&x);
ans=;
find(,dfn[x],dfn[x]+siz[x]-);
printf("%lld\n",ans%mod);
}
}
return ;
}
「LuoguP3384」【模板】树链剖分的更多相关文章
- 「POJ3237」Tree(树链剖分)
题意 给棵n个点的树.边有边权然后有三种操作 1.CHANGE i v 将编号为i的边权变为v 2.NEGATE a b 将a到b的所有边权变为相反数. 3.QUERY a b 查询a b路径的最大边 ...
- 「HNOI2015」开店(树链剖分, 主席树)
/* 考虑将所求的值拆分 记每个点到根的路径长度为dis_i, 那么我们要求的就是\sum_{i = l} ^ r dis_i + dis[u] * (r - l + 1) - 2\sum_{i = ...
- luoguP3384 [模板]树链剖分
luogu P3384 [模板]树链剖分 题目 #include<iostream> #include<cstdlib> #include<cstdio> #inc ...
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
- [洛谷P3384] [模板] 树链剖分
题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...
- loj#6073. 「2017 山东一轮集训 Day5」距离(树链剖分 主席树)
题意 题目链接 Sol 首先对询问差分一下,我们就只需要统计\(u, v, lca(u, v), fa[lca(u, v)]\)到根的路径的贡献. 再把每个点与\(k\)的lca的距离差分一下,则只需 ...
- 模板 树链剖分BFS版本
//点和线段树都从1开始 //边使用vector vector<int> G[maxn]; ],num[maxn],iii[maxn],b[maxn],a[maxn],top[maxn], ...
- P3384 [模板] 树链剖分
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n, m, rt, mod, cnt, to ...
- 树链剖分详解(洛谷模板 P3384)
洛谷·[模板]树链剖分 写在前面 首先,在学树链剖分之前最好先把 LCA.树形DP.DFS序 这三个知识点学了 emm还有必备的 链式前向星.线段树 也要先学了. 如果这三个知识点没掌握好的话,树链剖 ...
- 『题解』洛谷P3384 【模板】树链剖分
Problem Portal Portal1: Luogu Description 如题,已知一棵包含\(N\)个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作\(1\): ...
随机推荐
- 接阿里云oss有感
看API,从头细看到尾,在这个过程中一定会找到你要找的东西.
- HTTP请求的缓存(Cache)机制
原文地址:http://small.aiweimeng.top/index.php/archives/58.html 先来一张图: ####下面简单的来描述一下HTTP Cache机制: 当资源资源第 ...
- IntelliJ IDEA出现:This file is indented with tabs instead of 4 spaces的问题解决
根据阿里巴巴Java开发手册,不能使用Tab字符,改成4个字符,设置如下: 注意:是不选择! 一定要选择这个:
- Ubuntu 16.04安装IntelliJ IDEA时快捷键冲突设置
解决快捷键冲突可以有如下方法: 1.直接修改IDEA的,但是不建议这么干,因为多平台时,或者去到另外一台电脑时,统一的快捷键能更快的适应新的开发环境. 2.通过修改系统默认的快捷键. 3.就这两种方式 ...
- MySQL安装总是失败,提示缺少Visual Studio 2013 Redistributable
MySQL安装总是失败,提示缺少Visual Studio 2013 Redistributable,但是很疑惑,我明明已经安装了呀,原来问题出在版本上,以下提供了一个可以匹配新版本mysql的版本: ...
- 【嵌入式Linux+ARM】GPIO操作
1.GPIO介绍 GPIO(general purpose i/o ports)意思为通用输入/输出端口,通俗的说就是一些引脚. 我们可以通过它们输出高低电平 或 读入引脚的状态. s3c2440中有 ...
- [Unit Testing] Fundamentals of Testing in Javascript
In this lesson, we’ll get the most fundamental understanding of what an automated test is in JavaScr ...
- ZT:150条毒鸡汤
1.照照镜子吧,还要什么段子? 2.多年过去,再回忆高考,其实本质上没有考到好与坏的说法,重要的是年轻人在一起,做份试题,然后决定去哪座城市做代购. 3.真正努力过的人,就会明白天赋的重要性. 4.转 ...
- poj 3169 Layout(差分约束)
Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6549 Accepted: 3168 Descriptio ...
- js 类继承extends
先看例子: <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <titl ...