求和VII

PROBLEM

时间限制: 2 Sec 内存限制: 256 MB

题目描述

master对树上的求和非常感兴趣。他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k次方和,而且每次的k可能是不同的。此处节点深度的定义是这个节点到根的路径上的边数。他把这个问题交给了pupil,但pupil并不会这么复杂的操作,你能帮他解决吗?

输入

第一行包含一个正整数n,表示树的节点数。

之后n−1行每行两个空格隔开的正整数i,j,表示树上的一条连接点i和点j的边。

之后一行一个正整数m,表示询问的数量。

之后每行三个空格隔开的正整数i,j,k,表示询问从点i到点j的路径上所有节点深度的k次方和。由于这个结果可能非常大,输出其对998244353取模的结果。

树的节点从1开始标号,其中1号节点为树的根。

输出

对于每组数据输出一行一个正整数表示取模后的结果。

样例输入

5

1 2

1 3

2 4

2 5

2

1 4 5

5 4 45

样例输出

33

503245989

提示

以下用d(i)表示第i个节点的深度。

对于样例中的树,有d(1)=0,d(2)=1,d(3)=1,d(4)=2,d(5)=2。

因此第一个询问答案为(25+15+05) mod 998244353=33,第二个询问答案为(245+145+245) mod 998244353=503245989。

对于30%的数据,1≤n,m≤100;

对于60%的数据,1≤n,m≤1000;

对于100%的数据,1≤n,m≤300000,1≤k≤50。

SOLUTION

预处理每个点到根节点的50个和(k<=50) sum[i][k]

对每个询问x,y,求la = lca(x,y)。

答案就是sum[x][k]+sum[y][k]-sum[la][k]-sum[anc[la][0]][k];

CODE

  1. #define IN_PC() freopen("C:\\Users\\hz\\Desktop\\in.txt","r",stdin)
  2. #define IN_LB() freopen("C:\\Users\\acm2018\\Desktop\\in.txt","r",stdin)
  3. #define OUT_PC() freopen("C:\\Users\\hz\\Desktop\\out.txt","w",stdout)
  4. #define OUT_LB() freopen("C:\\Users\\acm2018\\Desktop\\out.txt","w",stdout)
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. typedef long long ll;
  8. const int MAXN = 3e5 + 5;
  9. const int INF = 0x3f3f3f3f;
  10. const ll MOD = 998244353;
  11. int anc[MAXN][20],deep[MAXN],t;
  12. ll sum[MAXN][55];
  13. struct edge {
  14. int v,nex;
  15. } ed[MAXN*2];
  16. int head[MAXN],cnt;
  17. void addedge(int u,int v) {
  18. cnt++;
  19. ed[cnt].v = v;
  20. ed[cnt].nex = head[u];
  21. head[u] = cnt;
  22. }
  23. queue<int> q;
  24. void bfs() {
  25. q.push(1);
  26. deep[1] = 0;
  27. while(q.size()) {
  28. int x = q.front();
  29. q.pop();
  30. for(int i=head[x]; i; i=ed[i].nex) {
  31. int y = ed[i].v;
  32. if(deep[y]||y==1)continue;
  33. deep[y] = deep[x]+1;
  34. ll base = deep[y];
  35. for(int i=1;i<=50;i++){
  36. sum[y][i] = (sum[x][i]+base)%MOD;
  37. base=base*deep[y]%MOD;
  38. }
  39. anc[y][0] = x;
  40. for(int j=1;j<=t;j++){
  41. anc[y][j] = anc[anc[y][j-1]][j-1];
  42. }
  43. q.push(y);
  44. }
  45. }
  46. }
  47. int lca(int x,int y) {
  48. if(deep[x]<deep[y])swap(x,y);
  49. for(int i=t; i>=0; i--) //to same deep;
  50. if(deep[y]<=deep[anc[x][i]])
  51. x = anc[x][i];
  52. if(x==y)return x;
  53. for(int i=t; i>=0; i--)
  54. if(anc[x][i]!=anc[y][i]) {
  55. x = anc[x][i];
  56. y = anc[y][i];
  57. }
  58. return anc[x][0];
  59. }
  60. int main() {
  61. // IN_LB();
  62. int n;
  63. scanf("%d",&n);
  64. t = (int)(log(n)/log(2))+1;
  65. for(int i=0; i<n-1; i++) {
  66. int u,v;
  67. scanf("%d%d",&u,&v);
  68. addedge(u,v);
  69. addedge(v,u);
  70. }
  71. bfs();
  72. int m;
  73. scanf("%d",&m);
  74. for(int i=0; i<m; i++) {
  75. int x,y,k;
  76. scanf("%d%d%d",&x,&y,&k);
  77. int la = lca(x,y);
  78. printf("%lld\n",(sum[x][k]+sum[y][k]-sum[la][k]-sum[anc[la][0]][k]+MOD+MOD)%MOD);
  79. }
  80. return 0;
  81. }

【LCA】求和VII @北京OI2018的更多相关文章

  1. 求和VII

    问题 K: 求和VII 时间限制: 2 Sec  内存限制: 256 MB提交: 422  解决: 53[提交] [状态] [讨论版] [命题人:admin] 题目描述 master对树上的求和非常感 ...

  2. HDOJ多校联合第六场

    先一道一道题慢慢补上, 1009.题意,一棵N(N<=50000)个节点的树,每个节点上有一个字母值,给定一个串S0(|S0| <=30),q个询问,(q<=50000),每次询问经 ...

  3. 【BZOJ5293】[BJOI2018]求和(前缀和,LCA)

    [BZOJ5293][BJOI2018]求和(前缀和,LCA) 题面 BZOJ 洛谷 题解 送分题??? 预处理一下\(k\)次方的前缀和. 然后求个\(LCA\)就做完了?... #include& ...

  4. BZOJ5293:[BJOI2018]求和(LCA,差分)

    Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k  次方和,而且每次的k 可能是不同的.此处节点深度的定义是这个节点 ...

  5. LCA+差分【p4427】[BJOI2018]求和

    Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的\(k\) 次方和,而且每次的\(k\) 可能是不同的.此处节点深度的 ...

  6. 【BJOI2018】求和 - 倍增LCA

    题目描述 $master$ 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的$k$次方和,而且每次的$k$可能是不同的.此处节点深度的定义是这个节点到根的路 ...

  7. 北京师范大学第十五届ACM决赛-重现赛 B Borrow Classroom (树 ——LCA )

    链接:https://ac.nowcoder.com/acm/contest/3/B 来源:牛客网 Borrow Classroom 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 2 ...

  8. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  9. 在线倍增法求LCA专题

    1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自 ...

随机推荐

  1. Python 命令模式和交互模式

    命令模式 在系统CMD命名模式下执行 命令执行到脚本所在目录 执行python Test.py 可直接一次执行完脚本里面所有的语句 交互模式下 一行一行执行

  2. ELK 使用4-Kafka + zookpeer

    一.zookpeer操作 1.登录 /application/elk/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 2.查看结构 ls / 上面的显示结果 ...

  3. BZOJ4816 [Sdoi2017]数字表格 数论 莫比乌斯反演

    原文链接http://www.cnblogs.com/zhouzhendong/p/8666106.html 题目传送门 - BZOJ4816 题意 定义$f(0)=0,f(1)=1,f(i)=f(i ...

  4. UOJ#219/BZOJ4650 [NOI2016]优秀的拆分 字符串 SA ST表

    原文链接http://www.cnblogs.com/zhouzhendong/p/9025092.html 题目传送门 - UOJ#219 (推荐,题面清晰) 题目传送门 - BZOJ4650 题意 ...

  5. 记录一次惊心动魄的sql去重

    )) )) url 为判重依据,保留最大id其他的数据状态改为删除状态. concat()函数,为字符串拼接函数 从外到内分析sql 第一层四个条件界定,第一个是source渠道,第二个是未删除状态, ...

  6. quratz启动流程

    SchedulerFactory在创建quartzScheduler的过程中,将会读取配置参数,初始化各个组件. 1.启动流程图 2.ThreadPool 一般是使用SimpleThreadPool, ...

  7. IDEA创建javaSE项目

  8. LoadRunner服务水平协议SLA

    服务水平协议 (或称 SLA)是以插入的事务为设置对象来为负载测试场景定义的具体目标. Analysis 将这些目标与 LoadRunner在运行过程中收集和存储的性能相关数据进行比较,然后确定目标的 ...

  9. 1402 后缀数组 (hash+二分)

    描述 后缀数组 (SA) 是一种重要的数据结构,通常使用倍增或者DC3算法实现,这超出了我们的讨论范围.在本题中,我们希望使用快排.Hash与二分实现一个简单的 O(n log^2⁡n ) 的后缀数组 ...

  10. node.js监听文件变化

    前言 随着前端技术的飞速发展,前端开发也从原始的刀耕火种,向着工程化效率化的方向发展.在各种开发框架之外,打包编译等技术也是层出不穷,开发体验也是越来越好.例如HMR,让我们的更新可以即时可见,告别了 ...