【LCA】求和VII @北京OI2018
求和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的更多相关文章
- 求和VII
问题 K: 求和VII 时间限制: 2 Sec 内存限制: 256 MB提交: 422 解决: 53[提交] [状态] [讨论版] [命题人:admin] 题目描述 master对树上的求和非常感 ...
- HDOJ多校联合第六场
先一道一道题慢慢补上, 1009.题意,一棵N(N<=50000)个节点的树,每个节点上有一个字母值,给定一个串S0(|S0| <=30),q个询问,(q<=50000),每次询问经 ...
- 【BZOJ5293】[BJOI2018]求和(前缀和,LCA)
[BZOJ5293][BJOI2018]求和(前缀和,LCA) 题面 BZOJ 洛谷 题解 送分题??? 预处理一下\(k\)次方的前缀和. 然后求个\(LCA\)就做完了?... #include& ...
- BZOJ5293:[BJOI2018]求和(LCA,差分)
Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k 次方和,而且每次的k 可能是不同的.此处节点深度的定义是这个节点 ...
- LCA+差分【p4427】[BJOI2018]求和
Description master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的\(k\) 次方和,而且每次的\(k\) 可能是不同的.此处节点深度的 ...
- 【BJOI2018】求和 - 倍增LCA
题目描述 $master$ 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的$k$次方和,而且每次的$k$可能是不同的.此处节点深度的定义是这个节点到根的路 ...
- 北京师范大学第十五届ACM决赛-重现赛 B Borrow Classroom (树 ——LCA )
链接:https://ac.nowcoder.com/acm/contest/3/B 来源:牛客网 Borrow Classroom 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 2 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- 在线倍增法求LCA专题
1.cojs 186. [USACO Oct08] 牧场旅行 ★★ 输入文件:pwalk.in 输出文件:pwalk.out 简单对比时间限制:1 s 内存限制:128 MB n个被自 ...
随机推荐
- [转] 安装npm全局包提示权限不够
方法1 sudo npm i -g npm 方法2 修改usr/local的权限.使用sudo有一个风险是安装包可能会运行自己的一些脚本,使sudo操作变的不可控,不安全.可以通过将/usr/loca ...
- 使用 curses 函数库管理基于文本的屏幕
curses 函数库提供了终端无关的方式来编写全屏幕的基于字符的程序.curses 还可以管理键盘,提供了一种简单易用的非阻塞字符输入模式. curses 函数库能够优化光标的移动并最小化需要对屏幕进 ...
- Dapper Helper
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...
- python全栈开发day98-DRF
1.CBV源码流程 2.restful协议 1 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性 2 面向资源架构(RO ...
- python全栈开发day70-Django中间件
参考个人博客 http://wuchengyi.com/post/13/ 三.预习和扩展
- Python_python内置加密模块
数据加密: 对称加密:数据加密和解密使用相同的密钥,主要解决数据的机密性(DES,AES) 非对称加密(公匙加密):数据加密和解密使用的不同密钥,主要用于身份的验证(DSA,RSA) 单向加密:只能加 ...
- Python学习(三十一)—— Django之路由系统
转载自:http://www.cnblogs.com/liwenzhou/p/8271147.html Django的路由系统 Django 1.11版本 URLConf官方文档 URL配置(URLc ...
- 【python】廖雪峰python教程学习--基础
No1: 目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的 No2: 用r''表示''内部的字符串默认不转义 No3: 以'''开头,敲回车可以换行 No4: 布尔 ...
- Tomcat v9.0 Could not publish to the server. java.lang.IndexOutOfBoundsException
今天使用Tomcat启动一个java项目,出现报错: Could not publish to the server. java.lang.IndexOutOfBoundsException 众寻之下 ...
- shell delete with line number
If you want to delete lines 5 through 10 and 12: sed -e '5,10d;12d' file This will print the results ...