「GXOI / GZOI2019」旧词
确定这不是思博题
看起来很神仙,本来以为是\([LNOI2014]LCA\)的加强版,结果发现一个点的贡献是\(s_i\times (deep_i^k-(deep_i-1)^k)\),\(s_i\)就是这个点的子树内部\(1\)到\(x\)点的数量
我们发现我们在树剖的时候利用后面那个东西就能来更新答案和打标机啦
照样离线就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=5e4+5;
const int mod=998244353;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct Ask{int x,y,rk;}q[maxn];
struct E{int v,nxt;}e[maxn];
int deep[maxn],head[maxn],dfn[maxn],id[maxn],top[maxn],fa[maxn],son[maxn];
int sum[maxn],n,m,num,calc[maxn],Ans[maxn],k,__;
int tag[maxn<<2],l[maxn<<2],r[maxn<<2],w[maxn<<2],d[maxn<<2];
inline int cmp(Ask A,Ask B) {return A.x<B.x;}
inline void add(int x,int y) {
e[++num].v=y;e[num].nxt=head[x];head[x]=num;
}
inline int ksm(int a,int b) {
int S=1;
while(b) {if(b&1) S=(1ll*S*a)%mod;b>>=1;a=(1ll*a*a)%mod;}
return S;
}
void dfs1(int x) {
sum[x]=1;
if(!calc[deep[x]])
calc[deep[x]]=(ksm(deep[x],k)-ksm(deep[x]-1,k)+mod)%mod;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1;fa[e[i].v]=x;
dfs1(e[i].v);sum[x]+=sum[e[i].v];
if(sum[e[i].v]>sum[son[x]]) son[x]=e[i].v;
}
}
void dfs2(int x,int topf) {
top[x]=topf,dfn[x]=++__,id[__]=x;
if(son[x]) dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(!top[e[i].v]) dfs2(e[i].v,e[i].v);
}
void build(int x,int y,int i) {
l[i]=x,r[i]=y;
if(x==y) {w[i]=calc[deep[id[x]]];return;}
int mid=x+y>>1;
build(x,mid,i<<1),build(mid+1,y,i<<1|1);
w[i]=(w[i<<1]+w[i<<1|1])%mod;
}
inline void pushdown(int i) {
if(!tag[i]) return;
tag[i<<1]+=tag[i];tag[i<<1|1]+=tag[i];
d[i<<1]=(d[i<<1]+1ll*w[i<<1]*tag[i]%mod)%mod;
d[i<<1|1]=(d[i<<1|1]+1ll*w[i<<1|1]*tag[i]%mod)%mod;
tag[i]=0;
}
void change(int x,int y,int i) {
if(x<=l[i]&&y>=r[i]) {
d[i]=(d[i]+w[i])%mod;
tag[i]++;
return;
}
pushdown(i);
int mid=l[i]+r[i]>>1;
if(x<=mid) change(x,y,i<<1);
if(y>mid) change(x,y,i<<1|1);
d[i]=(d[i<<1]+d[i<<1|1])%mod;
}
int query(int x,int y,int i) {
if(x<=l[i]&&y>=r[i]) return d[i];
pushdown(i);
int mid=l[i]+r[i]>>1,tot=0;
if(x<=mid) tot=(tot+query(x,y,i<<1))%mod;
if(y>mid) tot=(tot+query(x,y,i<<1|1))%mod;
return tot;
}
inline void modify(int x) {
while(top[x])
change(dfn[top[x]],dfn[x],1),x=fa[top[x]];
}
inline int ask(int x) {
int tmp=0;
while(top[x])
tmp=(tmp+query(dfn[top[x]],dfn[x],1))%mod,x=fa[top[x]];
return tmp;
}
int main() {
n=read(),m=read(),k=read();
for(re int x,i=2;i<=n;i++)
x=read(),add(x,i);
calc[1]=deep[1]=1,dfs1(1),dfs2(1,1);build(1,n,1);
for(re int i=1;i<=m;i++)
q[i].x=read(),q[i].y=read(),q[i].rk=i;
std::sort(q+1,q+m+1,cmp);int now=1;
for(re int i=1;i<=n;i++) {
modify(i);
while(now<=m&&q[now].x==i)
Ans[q[now].rk]=ask(q[now].y),now++;
}
for(re int i=1;i<=m;i++) printf("%d\n",Ans[i]);
return 0;
}
「GXOI / GZOI2019」旧词的更多相关文章
- 【LOJ】#3088. 「GXOI / GZOI2019」旧词
LOJ#3088. 「GXOI / GZOI2019」旧词 不懂啊5e4感觉有点小 就是离线询问,在每个x上挂上y的询问 然后树剖,每个节点维护轻儿子中已经被加入的点的个数个数乘上\(dep[u]^{ ...
- LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)
题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...
- 「GXOI / GZOI2019」简要题解
「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...
- LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位
#3083. 「GXOI / GZOI2019」与或和 题目大意 给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和.\(OR(|)\)之和. 数据范围 \(1 ...
- Loj #3085. 「GXOI / GZOI2019」特技飞行
Loj #3085. 「GXOI / GZOI2019」特技飞行 题目描述 公元 \(9012\) 年,Z 市的航空基地计划举行一场特技飞行表演.表演的场地可以看作一个二维平面直角坐标系,其中横坐标代 ...
- 【LOJ】#3087. 「GXOI / GZOI2019」旅行者
LOJ#3087. 「GXOI / GZOI2019」旅行者 正着求一遍dij,反着求一遍,然后枚举每条边,从u到v,如果到u最近的点和v能到的最近的点不同,那么可以更新答案 没了 #include ...
- 【LOJ】#3086. 「GXOI / GZOI2019」逼死强迫症
LOJ#3086. 「GXOI / GZOI2019」逼死强迫症 这个就是设状态为\(S,j\)表示轮廓线为\(S\),然后用的1×1个数为j 列出矩阵转移 这样会算重两个边相邻的,只要算出斐波那契数 ...
- 【LOJ】#3085. 「GXOI / GZOI2019」特技飞行
LOJ#3085. 「GXOI / GZOI2019」特技飞行 这显然是两道题,求\(C\)是一个曼哈顿转切比雪夫后的线段树扫描线 求\(AB\),对向交换最大化和擦身而过最大化一定分别为最大值和最小 ...
- 【LOJ】#3083. 「GXOI / GZOI2019」与或和
LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置 ...
随机推荐
- 请比较throw 合throws的区别
throw语句用在方法体内,表示抛出异常.throws语句用在方法声明的后面,表示再抛出异常,由该方法的调用者来处理.throws主要声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常. ...
- 百度Ueditor编辑器
百度的Ueditor编辑器出于安全性考虑,用户在html模式下粘贴进去的html文档会自动被去除样式和转义.虽然安全的,但是非常不方便. 1. ueditor.config.js 做出如下修改即可: ...
- Asp.net MVC流程简述
先上个图 步骤一 IIS 当请求到达我们的服务器时,在asp.net取得控制之前,windows操作系统的核心组件 HTTP.SYS一直在监听请求端口, 接下来asp.net会通知所有注册的ht ...
- PHP报错Deprecated: Function ereg_replace() is deprecated in
可能用了PHP5.3乃至更高的PHP版本,目前DEDE中有很多地方的正则函数都用的ereg_replace,而这个函数现在在PHP5.3中已经被废止了. 解决办法: 如果一定要用php5.3,请修改p ...
- 关于WebSocket协议
WebSocket是单个TCP连接上进行全双工通信的协议 在WebSocket的API中,客户端与服务器只需要进行一次握手就可以保持持久的连接,并可以双向传输数据 与HTTP不同的是,WebSocke ...
- 微信小程序“满月”:尝鲜之后你还用过它吗?
距离 2017 年 1 月 9 日微信小程序上线,整整过去了一个月时间.和互联网时代每天出现的众多新鲜事物相似,小程序甫一诞生,立即占据了各大科技媒体网站头屏并引起社交圈的兴奋讨论.由于背靠微信,纷纷 ...
- 专访阿里资深研发工程师窦贤明:PG与商业数据库差距并不明显
窦贤明认为, 支持类型.功能和语法丰富,性能优良 9月24日,窦贤明将参加在北京举办的线下活动,并做主题为<Greenplum分片案例分析>的分享.值此,他分享了PG.工作上的一些经历 ...
- 如何在C/S下打印报表
java应用有不少是C/S模式,在C/S模式下,同样可以调用API接口运算报表.CSReport是C/S模式下的报表控件类,在这个类中可以获得报表的显示面板.获得报表的打印面板.显示报表打印窗口 ...
- BASE_DIR 拼接文件路径
# C:/Disk_D/pycharm_stu/macboy/blog/views/tt.py 当前文件绝对路径 BASE_DIR = os.path.dirname(os.path.dirname( ...
- 【Java】多线程
class RunnableDemo implements Runnable { private Thread t; private String threadName; RunnableDemo( ...