求和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. 如何访问https的网站?-【httpclient】

    备注:本处代码使用groovy和httpclient4.3作为例子进行讲述 在普通方式下,当使用httpclient进行访问某个网站时,大致使用如下的代码进行访问: CloseableHttpClie ...

  2. 【Android】Android 中string-array的用法

    在Android中,用string-array是一种简单的提取XML资源文件数据的方法. 例子如下: 把相应的数据放到values文件夹的arrays.xml文件里 <?xml version= ...

  3. MySQL 5.7 模式(SQL_MODE)详细说明 转

    5.7 默认模式: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION ...

  4. LVM分区无损增减

    http://www.361way.com/change-lvm-size/1792.html

  5. Python题目练习(二)

    1.如何实现对python列表去重,并保持原来顺序 li = [1,2,5,3,1,6,3,8,0,3,2,4] l = [] for i in li: if i not in l: l.append ...

  6. springmvc+ajax——第三讲(post请求)

    在ajax01.html中增加个input标签: 在ajax的js中增加: 在controller中仍然使用getParamter():

  7. web发展阶段简介

     web1.0.web2.0和web3.0的区别前言: 其实并没有什么所谓的2.0.3.0,因为你没法准确的界定它是什么样的应用,也没法界定它是什么时候开始的,什么时候结束,它只是互联网本身发展的一种 ...

  8. POJ 2155 Matrix 【二维树状数组】(二维单点查询经典题)

    <题目链接> 题目大意: 给出一个初始值全为0的矩阵,对其进行两个操作. 1.给出一个子矩阵的左上角和右上角坐标,这两个坐标所代表的矩阵内0变成1,1变成0. 2.查询某个坐标的点的值. ...

  9. hdu 1237 简单计算器 (表达式求值)【stack】

    <题目链接> 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值.  Input测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符, ...

  10. 从小白到区块链工程师:第一阶段:Go语言中的函数学习(6)

    一. 为什么要有函数 我们在以后的编码过程中,有很多代码会重复出现,这些重复实现的代码,我们不需要每次需要用到的时候都编写,我们将重复的代码封装起来.比如在一个网站中,无论是消费的金额还是积分的积累等 ...