【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个被自 ...
随机推荐
- POJ 1273 Drainage Ditches【最大流模版】
题意:现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条有向水渠,给出这n条水渠所连接的点和所能流过的最大流量,求从源点到汇点能流过的最大流量 Dinic #include<iost ...
- Linux-GLIBCXX版本过低导致编译错误--version `GLIBCXX_3.4.20' not found
最近在CentOS6.2上安装protobuf2.4.1,编译的时候出现如下错误: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not fo ...
- move_uploaded_file中文乱码
move_uploaded_file($_FILES['file']['tmp_name'],iconv("UTF-8","gb2312",$filname)
- mysql inner jion多表查询
select vtiger_users.id, vtiger_users.user_name, vtiger_role.rolename FROM vtiger_users inner join vt ...
- [转]EndNote导入IEEE文献的方法
EndNote导入IEEE文献的方法.IEEE虽然可以批量导出,但是批量导出的是CSV格式.如果想导入到EndNote,需要一个个文献的导入.本文介绍一下IEEE导出文献并导入到EndNote的方法. ...
- WINDOWS 2008Server 配置nginx 反向代理服务器 安装成服务
本案例有用过可行 反向代理就是是网站通过一台机器发布到公网,客户访问的时候是直接访问那台代理机器的,然后通过那台机器才访问到内网网站. 0.先要在域名官网上面配置域名对应的IP地址,然后要在自己路 ...
- Zk 集群概念
https://blog.csdn.net/gs80140/article/details/51496925
- Hbase原理| 优化
GFS -->hdfsmapreduce --->hadoop mrbigtable-->hbase HBase是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统 海量存储:列式 ...
- sql的with as用法
http://www.cnblogs.com/linjiqin/archive/2013/06/24/3152667.html
- Lock为线程上锁,防止数据混乱
用法: 先实例化 lock = threading.Lock() 1. lock.acquire() 上锁 需上锁代码 lock.release() 解锁 2. with lock: 上下两种方式都 ...