[GX/GZOI2019]旧词(树上差分+树剖+线段树)
考虑k=1的做法:这是一道原题,我还写过题解,其实挺水的,但当时我菜还是看题解的:https://www.cnblogs.com/hfctf0210/p/10187947.html。其实就是树上差分后值为1。
考虑k>1的做法:其实可以再次树上差分,给每个点i赋值v[i]=dep[i]k-dep[i-1]k,然后还是和原来一样开一棵线段树,记录一个val[rt]表示当前节点内区间v值的和,以及sum[rt]表示区间值。修改时打标记,只需要将sum[rt]+=v*val[rt],lazy[rt]+=v即可。树剖一下即可。
#include<bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef pair<int,int>pii;
const int N=,mod=;
int n,Q,k,cnt,dep[N],fa[N],pw[N],sz[N],son[N],top[N],id[N],dfx[N];
int ans[N],sum[N<<],val[N<<],lazy[N<<];
vector<int>G[N];
vector<pii>vec[N];
int qpow(int a,int b)
{
int ret=;
while(b)
{
if(b&)ret=1ll*ret*a%mod;
a=1ll*a*a%mod,b>>=;
}
return ret;
}
void dfs(int u)
{
dep[u]=dep[fa[u]]+,sz[u]=;
for(int i=;i<G[u].size();i++)
if(G[u][i]!=fa[u])
{
dfs(G[u][i]),sz[u]+=sz[G[u][i]];
if(sz[G[u][i]]>sz[son[u]])son[u]=G[u][i];
}
}
void dfs2(int u,int tp)
{
top[u]=tp,id[u]=++cnt,dfx[cnt]=u;
if(son[u])dfs2(son[u],tp);
for(int i=;i<G[u].size();i++)
if(G[u][i]!=fa[u]&&G[u][i]!=son[u])dfs2(G[u][i],G[u][i]);
}
void build(int l,int r,int rt)
{
if(l==r){val[rt]=pw[dep[dfx[l]]];return;}
int mid=l+r>>;
build(lson),build(rson);
val[rt]=(val[rt<<]+val[rt<<|])%mod;
}
void pushdown(int rt)
{
if(!lazy[rt])return;
int v=lazy[rt];lazy[rt]=;
lazy[rt<<]=(lazy[rt<<]+v)%mod,sum[rt<<]=(sum[rt<<]+1ll*v*val[rt<<])%mod;
lazy[rt<<|]=(lazy[rt<<|]+v)%mod,sum[rt<<|]=(sum[rt<<|]+1ll*v*val[rt<<|])%mod;
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){lazy[rt]++,sum[rt]=(sum[rt]+val[rt])%mod;return;}
pushdown(rt);
int mid=l+r>>;
if(L<=mid)update(L,R,lson);
if(R>mid)update(L,R,rson);
sum[rt]=(sum[rt<<]+sum[rt<<|])%mod;
}
void Update(int u)
{
while(top[u]!=)update(id[top[u]],id[u],,n,),u=fa[top[u]];
update(,id[u],,n,);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
pushdown(rt);
int mid=l+r>>,ret=;
if(L<=mid)ret=(ret+query(L,R,lson))%mod;
if(R>mid)ret=(ret+query(L,R,rson))%mod;
return ret;
}
int Query(int u)
{
int ret=;
while(top[u]!=)ret=(ret+query(id[top[u]],id[u],,n,))%mod,u=fa[top[u]];
ret=(ret+query(,id[u],,n,))%mod;
return ret;
}
int main()
{
scanf("%d%d%d",&n,&Q,&k);
for(int i=;i<=n;i++)pw[i]=(qpow(i,k)-qpow(i-,k)+mod)%mod;
for(int i=;i<=n;i++)scanf("%d",&fa[i]),G[fa[i]].push_back(i);
dfs(),dfs2(,);
build(,n,);
for(int i=,x,y;i<=Q;i++)scanf("%d%d",&x,&y),vec[x].push_back(pii(y,i));
for(int i=;i<=n;i++)
{
Update(i);
for(int j=;j<vec[i].size();j++)ans[vec[i][j].second]=Query(vec[i][j].first);
}
for(int i=;i<=Q;i++)printf("%d\n",ans[i]);
}
[GX/GZOI2019]旧词(树上差分+树剖+线段树)的更多相关文章
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
[BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...
- [LNOI2014]LCA(树剖+线段树)
\(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...
- [CF1007D]Ants[2-SAT+树剖+线段树优化建图]
题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...
- LUOGU P1967 货车运输(最大生成树+树剖+线段树)
传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
随机推荐
- Maven工程配置依赖
1.下载 安装 官网下载maven :http://maven.apache.org/download.cgi ,下载时候注意版本,IDEA旧版本如我用的2017在安装Maven时可能会报错,此时别下 ...
- 常用模块-正则re
常用模块之正则模块 """ 正则表达式与re模块的关系 1.正则表达式是一门独立的技术,任何语言均可使用 2.python中要想使用正则表达式需要通过re模块 " ...
- P2P平台被清盘后,你会怎样捍卫自身利益?
近段时间,P2P平台爆雷不断.很多交易金额过百亿的大型P2P平台也"晚节不保",跑路的跑路.倒闭的倒闭.清盘的清盘.从爆火到爆雷,P2P平台正应了那句话,"眼见他起高楼, ...
- 浅入深出Java输入输出流主线知识梳理
Java把不同类型的输入.输出,这些输入输出有些是在屏幕上.有些是在电脑文件上, 都抽象为流(Stream) 按流的方向,分为输入流与输出流,注意这里的输出输出是相对于程序而言的,如:如对于一个J ...
- arp攻击 (可查看同一局域网他人手机照片)
国家法律一定要遵守,知识要用在对的地方. 本贴只为了和大家交流学习,请勿用在其他地方,损害任何人的利益. 今天我,来说一下arp攻击的原理和教程 原理什么的还是自行百度好,因为专业的说明是严谨而又经得 ...
- JavaScript之HTML DOM Event
当鼠标在button上点击时,会在button上触发一个click事件.但是button是div的一个子元素, 在button里点击相当于在div里点击,是否click事件也会触发在div上?如果cl ...
- Vue-router(3)之 router-link 和 router-view 使用
router 导入 import Vue from 'vue' import Router from 'vue-router' import order from '@/view/New/order. ...
- potplayer记住播放进度
(右键——选项)F5——播放——记忆视频播放位置
- 寒假day13
今天看了计算机网络的相关面试题
- Linux(CENTOS7) Nginx负载均衡简单配置
负载均衡的作用 1.转发功能 按照一定的算法[权重.轮询],将客户端请求转发到不同应用服务器上,减轻单个服务器压力,提高系统并发量. 2.故障移除 通过心跳检测的方式,判断应用服务器当前是否可以正常工 ...