[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]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
随机推荐
- 三十一、CI框架之使用验证码
一.CI的验证码功能用着很是舒服,需要在根目录下新建一个captcha的验证码文件夹用于存放生产的图片,代码如下: 二.浏览器效果如下: 总结:关于验证码生产函数,有很多参数可以设置,包括字体,验证码 ...
- 十二、CI框架之数据库查询
一.在database文件中写明数据库相关信息 二.我们数据库中的表如图所示 三.在CI中查询数据库内容 四.在浏览器输出 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金 ...
- 刷题之Implement strStr()、Climbing Stairs
public class Solution { public int strStr(String haystack, String needle) { int big = haystack.lengt ...
- Linix CentOS6.5 下载安装图解(转)
CentOS 6.5系统镜像有32位和64位两个版本,生产服务器如果是大内存(4G以上内存) 建议安装64位版本CentOS-6.5-x86_64-bin-DVD1.iso 附:CentOS 6.5下 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 修饰符类型
C++ 允许在 char.int 和 double 数据类型前放置修饰符.修饰符用于改变基本类型的含义,所以它更能满足各种情境的需求. 下面列出了数据类型修饰符: signed unsigned lo ...
- POJ - 3659 Cell Phone Network(树形dp---树的最小点支配集)
题意:有N个点,N-1条边,任意两点可达,由此形成了一棵树.选取一个点a,它可覆盖自己以及与自己相邻的点,选取尽量少的点a,使得树中所有点都被覆盖,即求树的最小点支配集. 分析: 1.对于每一个点cu ...
- Django——CSRF防御
关于CSRF攻击原理在上一篇博客已经有过说明,这篇主要介绍下Django关于开启CSRF及CSRF工作机理.关于开启防御有两种,一种是全局开启,另一种是局部开启. 全局: 中间件 django.mid ...
- VMware Workstation 12 PRo密钥
注意:手动输入(起初复制输入,一个都没成功,不要偷懒哦) VMware Workstation 12序列号: 5A02H-AU243-TZJ49-GTC7K-3C61N
- android机器时间不同步导致网络请求出错
转自: https://blog.csdn.net/DeMonliuhui/article/details/82226601 获取网页时间代替系统时间 根据下列代码,我们就可以获取任何一个网址的时间( ...
- ubuntu16.04 pcl安装教程
https://blog.csdn.net/zkj126521/article/details/80157351 https://blog.csdn.net/e_small/article/detai ...