考虑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]旧词(树上差分+树剖+线段树)的更多相关文章

  1. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  2. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  3. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  4. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LUOGU P1967 货车运输(最大生成树+树剖+线段树)

    传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...

  8. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  9. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  10. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

随机推荐

  1. 阿里巴巴技术总监全解中台架构19页ppt

    //初创时,快速上线 单体架构至少撑了3年 //分布式,中间件基座 //平台化,内部是简单服务,对于业务侧就是快速上线 //平台化之后由于多平台协作问题,再次出现问题: 效率仍然不能匹配业务发展之需要 ...

  2. JDBC批处理方法

    每次新建Connection的时候相当于建了一座桥,每次一辆车(PreparedStatement)运送货物(ResultSet)成本太高! 每次都建立网络连接的时间远远大于本地的时间,为了处理大量的 ...

  3. 201909-2 小明种苹果(续) Java

    思路: 待补充 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc ...

  4. 在阿里云Centos7.6中部署nginx1.16+uwsgi2.0.18+Django2.0.4

    上次在网上找了一个在阿里云Centos7.6中部署nginx1.16+uwsgi2.0.18+Django2.0.4的文档,可能是这个文档不是最新版的,安装的时候遇到了很多问题, 最后跟一个大神要了一 ...

  5. spring boot集成mybatis(3) - mybatis generator 配置

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  6. 2020/2/1 PHP代码审计之任意文件读取及删除漏洞

    在开始学习之前先简单记录一下自己现在的思路吧..现在接触的基本都是无防护的漏洞也就是最简单的一些漏洞.我的想法就是以代审思路为主,之前一直在打CTF,白盒的思维我觉得和CTF这种黑盒有很大区别.自己的 ...

  7. 深入理解 Java —— GC 机制

    1. 基础知识 1.1 什么是垃圾回收? 程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存资源,最终将导致内存溢出,所以对内存资源的管理非常重要. 垃圾回收就是对这些无效资 ...

  8. 干货 | AI人脸识别之人脸搜索

    本文档将利用京东云AI SDK来实践人脸识别中的人脸搜索功能,主要涉及到分组创建/删除.分组列表获取.人脸创建/删除.人脸搜索,本次实操的最终效果是:创建一个人脸库,拿一张图片在人脸库中搜索出相似度最 ...

  9. TCP三次握手和四次挥手相关

    客户端A 服务端BSYN (建立连接位标识 1为建立联机) ACK (确认位标识 1为确认) seq (一个随机顺序码) ack(一个确认号码,通常为seq+1) 三次握手:1.A 发起建立 连接 的 ...

  10. 201771010123汪慧和《面向对象程序设计JAVA》第九周实验总结

    一.理论部分 1.异常 (1)异常处理的任务就是将控制权从错误产生的地方转移给能够处理这种情况的错误处理器. (2)程序中可能出现的错误和问题:a.用户输入错误.b.设备错误.c.物理限制.d.代码错 ...