求和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

#define IN_PC() freopen("C:\\Users\\hz\\Desktop\\in.txt","r",stdin)
#define IN_LB() freopen("C:\\Users\\acm2018\\Desktop\\in.txt","r",stdin)
#define OUT_PC() freopen("C:\\Users\\hz\\Desktop\\out.txt","w",stdout)
#define OUT_LB() freopen("C:\\Users\\acm2018\\Desktop\\out.txt","w",stdout)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 998244353; int anc[MAXN][20],deep[MAXN],t;
ll sum[MAXN][55]; struct edge {
int v,nex;
} ed[MAXN*2]; int head[MAXN],cnt; void addedge(int u,int v) {
cnt++;
ed[cnt].v = v;
ed[cnt].nex = head[u];
head[u] = cnt;
} queue<int> q; void bfs() {
q.push(1);
deep[1] = 0;
while(q.size()) {
int x = q.front();
q.pop();
for(int i=head[x]; i; i=ed[i].nex) {
int y = ed[i].v;
if(deep[y]||y==1)continue;
deep[y] = deep[x]+1;
ll base = deep[y];
for(int i=1;i<=50;i++){
sum[y][i] = (sum[x][i]+base)%MOD;
base=base*deep[y]%MOD;
}
anc[y][0] = x;
for(int j=1;j<=t;j++){
anc[y][j] = anc[anc[y][j-1]][j-1];
}
q.push(y);
}
}
} int lca(int x,int y) {
if(deep[x]<deep[y])swap(x,y);
for(int i=t; i>=0; i--) //to same deep;
if(deep[y]<=deep[anc[x][i]])
x = anc[x][i];
if(x==y)return x;
for(int i=t; i>=0; i--)
if(anc[x][i]!=anc[y][i]) {
x = anc[x][i];
y = anc[y][i];
}
return anc[x][0];
} int main() {
// IN_LB();
int n;
scanf("%d",&n);
t = (int)(log(n)/log(2))+1;
for(int i=0; i<n-1; i++) {
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
bfs();
int m;
scanf("%d",&m);
for(int i=0; i<m; i++) {
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
int la = lca(x,y);
printf("%lld\n",(sum[x][k]+sum[y][k]-sum[la][k]-sum[anc[la][0]][k]+MOD+MOD)%MOD);
}
return 0;
}

【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. .net core 发布后提示Start error

    纪录篇: 发布Core版本的项目后一直提示error,通过网络查询资料后确认梳理问题的逻辑   1.验证环境是否支持,开发环境及server环境        参考:https://docs.micr ...

  2. 多线程外排序解决大数据排序问题2(最小堆并行k路归并)

    转自:AIfred 事实证明外排序的效率主要依赖于磁盘,归并阶段采用K路归并可以显著减少IO量,最小堆并行k路归并,效率倍增. 二路归并的思路会导致非常多冗余的磁盘访问,两组两组合并确定的是当前的相对 ...

  3. SSH免密远程登陆及详解

    SSH(安全外壳协议):为建立在应用层和传输层基础上的安全协议,ssh是目前较为可靠,专门为远程登陆,会话和其他网络服务提供安全 协议.利用ssh协议可以有效的防止远程管理过程中的信息泄露问题,传统的 ...

  4. C#中的 Stream

    目录: 什么是Stream? 什么是字节序列? Stream的构造函数 Stream的重要属性及方法 Stream的示例 Stream异步读写 Stream 和其子类的类图 本章总结 什么是Strea ...

  5. 3、Qt Project之Socket网络编程

    Socket网络编程  Step1:首先完成整个界面的设计 <?xml version="1.0" encoding="UTF-8"?> <u ...

  6. Nginx 关闭防火墙

    关闭防火墙 1) 重启后生效  开启: chkconfig iptables on  关闭: chkconfig iptables off    2) 即时生效,重启后失效  开启: service ...

  7. 从零搭建 ES 搜索服务(三)同义词搜索

    一.前言 上篇介绍了 ES 的基础搜索,能满足我们基本的需求,然而在实际使用中还可能希望搜索「番茄」能将包含「西红柿」的结果也罗列出来,本篇将介绍如何实现同义词之间的搜索. 二.安装 ES 同义词插件 ...

  8. Web Component

    前言 Web Component不是新东西,几年前的技术,但是受限于浏览器兼容性,一直没有大规模应用在项目里,直到现在(2018年年末),除IE仍不支持之外,其它主流浏览器都支持Web Compone ...

  9. [洛谷P1063][NOIP2006]能量项链

    区间DP模板题 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗 ...

  10. Java内存空间的分配及回收

    Java中内存分为: 栈:存放简单数据类型变量(值和变量名都存在栈中),存放引用数据类型的变量名以及它所指向的实例的首地址. 堆:存放引用数据类型的实例. Java的垃圾回收 由一个后台线程gc进行垃 ...