题目链接:

[GXOI/GZOI2019]旧词

对于$k=1$的情况,可以参见[LNOI2014]LCA,将询问离线然后从$1$号点开始对这个点到根的路径链修改,每次询问就是对询问点到根路径链查询即可。

可以发现,如果一个点的贡献被记入答案,那么这个点到根的路径上所有点的贡献都会被记入答案。

那么对于$k>1$的情况,只要每次将路径上点$u$的权值都$+1$变成每次将路径上点$u$的权值都$+(dep[u]^k-(dep[u]-1)^k)$即可。

同样用线段树维护树剖序的区间权值和即可。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int mod=998244353;
int n,m,k;
int ans[50010];
int p[50010];
int son[50010];
int size[50010];
int f[50010];
int tot;
int head[50010];
int to[50010];
int nex[50010];
int dep[50010];
int top[50010];
int s[50010];
int q[50010];
int dfn;
int sum[400010];
int num[400010];
int tag[400010];
struct lty
{
int x,y,id;
}a[50010];
bool cmp(lty a,lty b)
{
return a.x<b.x;
}
int quick(int x,int y)
{
int res=1;
while(y)
{
if(y&1)
{
res=1ll*res*x%mod;
}
x=1ll*x*x%mod;
y>>=1;
}
return res;
}
void add_edge(int x,int y)
{
nex[++tot]=head[x];
head[x]=tot;
to[tot]=y;
}
int add(int x,int y)
{
if(x+y<mod)
{
return x+y;
}
else
{
return x+y-mod;
}
}
void dfs(int x)
{
size[x]=1;
for(int i=head[x];i;i=nex[i])
{
dep[to[i]]=dep[x]+1;
dfs(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]])
{
son[x]=to[i];
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
s[x]=++dfn;
q[dfn]=x;
if(son[x])
{
dfs2(son[x],tp);
}
for(int i=head[x];i;i=nex[i])
{
if(to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
void pushup(int rt)
{
sum[rt]=add(sum[rt<<1],sum[rt<<1|1]);
num[rt]=add(num[rt<<1],num[rt<<1|1]);
}
void pushdown(int rt)
{
if(tag[rt])
{
tag[rt<<1]=add(tag[rt],tag[rt<<1]);
tag[rt<<1|1]=add(tag[rt],tag[rt<<1|1]);
sum[rt<<1]=add(sum[rt<<1],1ll*tag[rt]*num[rt<<1]%mod);
sum[rt<<1|1]=add(sum[rt<<1|1],1ll*tag[rt]*num[rt<<1|1]%mod);
tag[rt]=0;
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
num[rt]=p[dep[q[l]]];
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
tag[rt]=add(tag[rt],1);
sum[rt]=add(sum[rt],num[rt]);
return ;
}
int mid=(l+r)>>1;
pushdown(rt);
if(L<=mid)
{
change(rt<<1,l,mid,L,R);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R);
}
pushup(rt);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return sum[rt];
}
int mid=(l+r)>>1;
int res=0;
pushdown(rt);
if(L<=mid)
{
res=add(res,query(rt<<1,l,mid,L,R));
}
if(R>mid)
{
res=add(res,query(rt<<1|1,mid+1,r,L,R));
}
return res;
}
void modify(int x)
{
while(top[x]!=1)
{
change(1,1,n,s[top[x]],s[x]);
x=f[top[x]];
}
change(1,1,n,1,s[x]);
}
int ask(int x)
{
int res=0;
while(top[x]!=1)
{
res=add(res,query(1,1,n,s[top[x]],s[x]));
x=f[top[x]];
}
res=add(res,query(1,1,n,1,s[x]));
return res;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
p[i]=(quick(i,k)-quick(i-1,k)+mod)%mod;
}
dep[1]=1;
for(int i=2;i<=n;i++)
{
scanf("%d",&f[i]);
add_edge(f[i],i);
}
dfs(1);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].id=i;
}
sort(a+1,a+1+m,cmp);
int now=0;
for(int i=1;i<=m;i++)
{
while(now<a[i].x)
{
now++;
modify(now);
}
ans[a[i].id]=ask(a[i].y);
}
for(int i=1;i<=m;i++)
{
printf("%d\n",ans[i]);
}
}

[LOJ3088][GXOI/GZOI2019]旧词——树链剖分+线段树的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. .Net移动开发平台 ,基于VisualStudio的可视化开发——Smobiler平台入门教程

    通过以下步骤,可以简单了解到如何下载Smobiler Designer(设计器).Client(客户端),以及如何通过设计器进行开发和调试移动应用,并在服务端部署.Cloud打包.访问您所开发的移动应 ...

  2. 菜鸟入门【ASP.NET Core】1:环境安装

    下载.NET Core SDK 下载地址:https://www.microsoft.com/net/download/windows https://www.microsoft.com/net/le ...

  3. spring通知执行的顺序

    点击下载本示例相关代码 关于spring aop的具体使用,暂时不在这里讲解,后面会特定来讲解,本次主要探讨spring中通知执行的顺序. spring中通知分为以下几种: before:前置通知,在 ...

  4. Spring MVC(一)五大核心组件和配置

    一,五大核心组件 1.DispatcherServlet 请求入口 2.HandlerMapping   请求派发,负责请求和控制器建立一一对应的关系 3.Controller   处理器 4.Mod ...

  5. axios 封装

    来自:https://www.jianshu.com/p/68d81da4e1ad 侵删 import axios from 'axios' import qs from 'qs' let baseu ...

  6. gitbook 入门教程之主题插件

    主题插件 目前 gitbook 提供三类文档: Book 文档,API 文档和 FAQ 文档. 其中,默认的也是最常使用的就是 Book 文档,如果想要了解其他两种文档模式,需要引入相应的主题插件. ...

  7. [Python] wxPython 高防Windows10记事本 (end...)

    1.开始 接触Python 也有一段时间了,o.o ,断断续续加起来没几天. 一般新学习一门新语言,除了必先输出一个 Hello World 外,都会以模拟 Windows 记事本来写一个结合自己想法 ...

  8. 升级Mac OS X上的git

    今天一打开visual studio code就提示我git版本low,需要升级,然后提供了一个下载链接(git官方下载地址:https://git-scm.com/),然后我就根据链接去下载了mac ...

  9. TestLink-Windows安装教程

    TestLink-Windows安装教程 QQ群交流:585499566 一.这篇文章的目的 以后工作中要使用Testlink来管理测试的流程,需要在本地或者Testlink服务器上练习使用,在个人本 ...

  10. mysqlbinlog 工具分析binlog日志

    MySQL的binlog 日志对于生产环境非常有用,任何时间对数据库的修改都会记录在binglog中:当数据发生增删改,创建数据库对象都会记录到binlog中,数据库的复制也是基于binlog进行同步 ...