Descriptioin

浮生有梦三千场
穷尽千里诗酒荒
徒把理想倾倒
不如早还乡

温一壶风尘的酒
独饮往事迢迢
举杯轻思量
泪如潮青丝留他方

——乌糟兽/愚青《旧词》

你已经解决了五个问题,不妨在这大树之下,吟唱旧词一首抒怀。最后的问题就是关于这棵树的,它的描述很简单。

给定一棵 \(n\) 个点的有根树,节点标号 \(1 \sim n\),11 号节点为根。
给定常数 \(k\) 。
给定 \(Q\) 个询问,每次询问给定 \(x,y\)。
求:

\(\sum\limits_{i\leq x} depth(lca(i,y))^k\)

\(lca(x,y)\) 表示节点 \(x\) 与节点 \(y\) 在有根树上的最近公共祖先。
\(depth(x)\) 表示节点 \(x\) 的深度,根节点的深度为 1。
由于答案可能很大,你只需要输出答案模 998244353 的结果。

Input

输入包含 \(n+Q\) 行。

第 1 行,三个正整数 \(n,Q,k\) 。

第 \(i=2 \sim n\) 行,每行有一个正整数 \(f_i,(1 \leq f_i \leq n)\),表示编号为 \(i\) 的节点的父亲节点的编号。

接下来 $ Q$ 行,每行两个正整数 \(x,y(1 \leq x,y \leq n)\),表示一次询问。

Output

输出包含 \(Q\) 行,每行一个整数,表示答案模 998244353 的结果。

Sample Input

5 5 2
1
4
1
2
4 3
5 4
2 5
1 2
3 2

Sample Output

15
11
5
1
6

HINT

样例解释
输入的树:

每个点的深度分别为 1,2,3,2,3。

第一个询问 \(x = 4,y = 3\),容易求出:

\(lca(1,3)=1,lca(2,3)=1,lca(3,3)=3,lca(4,3)=4\)
于是 \(depth(1) +depth(1) +depth(3) +depth(4) =1+1+9+4=15\) 。

数据范围 \(n\leq 50000,m\leq 50000,1\leq k \leq 10^9\)


想法

首先一句题外话,我真的很喜欢这种有些文学范儿的题~

言归正传!这个题跟 \([LNOI2014]LCA\) 很像,挺套路的。
离线,把所有询问按 \(x\) 从小到大排序后处理。
考虑当 \(k=1\) 时,将 \(1\leadsto [1,x]\) 每条路径上经过的点的值都加1,统计 \(1\leadsto y\) 路径上所有点的值之和就是答案

这样做的原理为 对于任意深度为 \(i\) 的点,它对答案的贡献为 $ i^1-(i-1)^1=1 $

那么当 \(k \neq 1\) 时也同理,任意深度为 \(i\) 的点对答案的贡献为 \(i^k-(i-1)^k=c\) ,路径上若经过这个点,则该点的值加 \(c\)
由于所有点深度固定,\(k\) 也固定, \(c\) 是很容易处理出来的。

至于如何修改与统计,那当然是树链剖分+线段树咯!(虽说 \(lct\) 也行,但想想那代码量与极大的常数还是放弃吧 )


代码

#include<cstdio>
#include<iostream>
#include<algorithm>using namespace std;int read(){int x=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();return x;
}const int N = 50005;
const int xzy = 998244353;
typedef long long ll;struct node{int v;node *nxt;
}pool[N],*h[N];
int cnt;
void addedge(int u,int v){node *p=&pool[++cnt];p->v=v;p->nxt=h[u];h[u]=p;
}int fa[N],son[N],dep[N],size[N];
void dfs1(int u){int v,sonnum=0;size[u]=1;for(node *p=h[u];p;p=p->nxt){dep[v=p->v]=dep[u]+1;dfs1(v);if(size[v]>sonnum) sonnum=size[v],son[u]=v;size[u]+=size[v];}
}
int top[N],w[N],rk[N],tot;
void dfs2(int u){int v=son[u];if(v){top[v]=top[u];w[v]=++tot;rk[tot]=v;dfs2(v);}for(node *p=h[u];p;p=p->nxt)if((v=p->v)!=son[u]){top[v]=v;w[v]=++tot;rk[tot]=v;dfs2(v);}
}int n,m,k;
int Pow_mod(int x,int y){int ret=1;while(y){if(y&1) ret=((ll)ret*x)%xzy;x=((ll)x*x)%xzy;y>>=1;}return ret;
}struct tree{tree *ch[2];int e,sum,lazy;
}pool2[N*2],*root;
int cnt2;
void build(tree *p,int l,int r){p->sum=p->lazy=0;if(l==r){p->e=(Pow_mod(dep[rk[l]],k)-Pow_mod(dep[rk[l]]-1,k)+xzy)%xzy;return;}int mid=(l+r)>>1;build(p->ch[0]=&pool2[++cnt2],l,mid);build(p->ch[1]=&pool2[++cnt2],mid+1,r);p->e=((ll)p->ch[0]->e+p->ch[1]->e)%xzy;
}
void update(tree *p) { p->sum=((ll)p->ch[0]->sum+p->ch[1]->sum)%xzy; }
void pushdown(tree *p){if(!p->lazy) return;for(int i=0;i<2;i++){(p->ch[i]->lazy+=p->lazy)%=xzy;p->ch[i]->sum=((ll)p->ch[i]->sum+1ll*p->lazy*p->ch[i]->e%xzy)%xzy;}p->lazy=0;
}
void change(tree *p,int l,int r,int L,int R){if(l==L && r==R){p->lazy++;p->sum=(p->sum+p->e)%xzy;return;}pushdown(p);int mid=(l+r)>>1;if(R<=mid) change(p->ch[0],l,mid,L,R);else if(L>mid) change(p->ch[1],mid+1,r,L,R);else{change(p->ch[0],l,mid,L,mid);change(p->ch[1],mid+1,r,mid+1,R);}update(p);
}
int query(tree *p,int l,int r,int L,int R){if(l==L && r==R) return p->sum;pushdown(p);int mid=(l+r)>>1;if(R<=mid) return query(p->ch[0],l,mid,L,R);else if(L>mid) return query(p->ch[1],mid+1,r,L,R);return (query(p->ch[0],l,mid,L,mid)+query(p->ch[1],mid+1,r,mid+1,R))%xzy;
}void add(int x){while(x){change(root,1,n,w[top[x]],w[x]);x=fa[top[x]];}
}
int ask(int x){int ret=0;while(x){(ret+=query(root,1,n,w[top[x]],w[x]))%=xzy;x=fa[top[x]];}return ret;
}struct data{int x,y,id;bool operator < (const data &b) const{ return x<b.x; }
}d[N];
int ans[N];int main()
{n=read(); m=read(); k=read();for(int i=2;i<=n;i++) {fa[i]=read();addedge(fa[i],i);}for(int i=0;i<m;i++) { d[i].x=read(); d[i].y=read(); d[i].id=i;}sort(d,d+m);dep[1]=1;dfs1(1);top[1]=1; w[1]=++tot; rk[tot]=1;dfs2(1);build(root=&pool2[++cnt2],1,n);int t=0;for(int i=0;i<m;i++){while(t<d[i].x) add(++t);ans[d[i].id]=ask(d[i].y);}for(int i=0;i<m;i++) printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/lindalee/p/11108200.html

[bzoj5507] [洛谷P5305] [gzoi2019]旧词相关推荐

  1. [GXOI/GZOI2019]旧词——树链剖分+线段树

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

  2. [数据结构专训][GXOI/GZOI2019]旧词,[hdu5118]GRE Words Once More!,[hdu6333]Problem B. Harvest of Apples

    文章目录 T1:[GXOI/GZOI2019]旧词 solution code T2:GRE Words Once More! solution code T3:Problem B. Harvest ...

  3. P5305-[GXOI/GZOI2019]旧词【树链剖分,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P5305 题目大意 给一棵有根树和kkk,QQQ次询问给出x,yx,yx,y求 ∑i=1xdepLCA(i,y)k\ ...

  4. 洛谷P3336 [ZJOI2013]话旧 题解

    洛谷P3336 [ZJOI2013]话旧 题解 题目链接:P3336 [ZJOI2013]话旧 题意:小林跟着银河队选手去了一趟宇宙比赛,耳濡目染,变得学术起来.回来后,他发现世界大变样了.比丘兽究级 ...

  5. 洛谷 P1127 词链

    词链 题目链接 题目描述 如果单词 X X X 的末字母与单词 Y Y Y 的首字母相同,则 X X X 与 Y Y Y 可以相连成 X . Y X.Y X.Y.(注意: X X X. Y Y Y 之 ...

  6. 洛谷-DFS-1101-单词方阵-个人AC题解及公共题解的笔记

    先上自己AC代码(博主这个代码修改过多次,只因代码长度过长) #include<bits/stdc++.h> using namespace std; #define MAXN 102 i ...

  7. 洛谷-DFS-1019-单词接龙-个人AC题解和公共AC题解笔记

    学习内容: 预处理 万能头文件 string的使用 话不多说,直奔主题 本人AC代码 #include<iostream> #include<cstdio> #include& ...

  8. 【GXOI / GZOI2019】【树链剖分】【线段树】旧词

    [题目描述] 浮生有梦三千场 穷尽千里诗酒荒 徒把理想倾倒 不如早还乡 温一壶风尘的酒 独饮往事迢迢 举杯轻思量 泪如潮青丝留他方 --乌糟兽/愚青<旧词> 你已经解决了五个问题,不妨在这 ...

  9. 洛谷 P1019 单词接龙 (DFS)

    题目传送门 当时一看到这题,蒟蒻的我还以为是DP,结果发现标签是搜索-- 这道题的难点在于思路和预处理,真正的搜索实现起来并不难.我们可以用一个贪心的思路,开一个dic数组记录每个单词的最小重复部分, ...

最新文章

  1. JVM最多支持多少个线程?
  2. 约瑟夫环形链表问题、丢手帕问题、剑指offer圆圈中最后一个数问题
  3. mtr命令详解诊断网络路由
  4. ASP.NET页面通过URL传递参数(一)(转载)
  5. [网络安全提高篇] 一〇六.SQL注入之手工注入和SQLMAP入门案例详解
  6. Java 集合框架部分面试题
  7. jmeter 线程执行顺序_软件接口测试工具Jmeter使用方法详解(一)
  8. JavaScript-包装类型
  9. 史上最全Nginx面试题及答案
  10. 过保金士顿SA400S37固态硬盘固件通病,不保存盘内数据如何救活?
  11. Integer division by zero
  12. 教你如何编写游戏外挂
  13. jQuery实现模拟微博发布框
  14. (实测可用)STM32CubeMX教程-STM32L431RCT6开发板研究串口通信(SPI flash)
  15. Python数据科学学习笔记之——机器学习专题
  16. AWS - Redshift - Unload 数据到S3产生的文件名
  17. windows硬盘读写测试
  18. 隐藏cmd,让电脑读出文字(中文发音),
  19. python——删除文件夹下的所有文件和子文件夹(含代码)
  20. 为什么开直通车后搜索上不来?手淘压制搜索如何解决?

热门文章

  1. 2022年安全员-A证考试题库及安全员-A证免费试题
  2. 微信开发自带版本管理的使用(图文)---推送,抓取,拉取,贮藏
  3. 商城App接入快递100
  4. JSP入门教程:JSP简明教程
  5. Gitee (码云)操作
  6. Ubuntu运行多个命令
  7. 苹果手机怎么在照片上添加文字_给微信拍照的照片添加文字,调整后期效果,手机两步搞定!...
  8. 第13章 多进程编程
  9. 十年海军为什么选择开启代码人生?
  10. 解决CSS子元素绝对定位致使父元素高度为0