问题 K: 求和VII

时间限制: 2 Sec  内存限制: 256 MB
提交: 422  解决: 53
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
const int mod=;
vector<int> a[];
int fa[],b[maxn],n,k;
ll sum[maxn][],ans;
queue<int> rec;
void init()//预处理每个点的1-50次方
{
for(int i=; i<=n; i++)
{
for(int j=; j<=; j++)
{
if(j==) sum[i][j]=b[i];
else sum[i][j]=sum[i][j-]*b[i]%mod;
}
}
}
void digui(int r,int t)//关键部分,递归求路径所有点的k次方
{
if(b[r]<b[t])
{
ans=(ans+sum[t][k])%mod;
digui(r,fa[t]);
}
else if(b[r]>b[t])
{
ans=(ans+sum[r][k])%mod;
digui(fa[r],t);
}
else if(b[r]==b[t]&&fa[r]==fa[t]&&r!=t)
{
ans=(ans+sum[r][k])%mod;
ans=(ans+sum[t][k])%mod;
ans=(ans+sum[fa[r]][k])%mod;
return ;
}
else if(r==t)
{
ans=(ans+sum[r][k])%mod;
return ;
}
else if(b[r]==b[t]&&fa[r]!=fa[t])
{
ans=(ans+sum[r][k])%mod;
ans=(ans+sum[t][k])%mod;
digui(fa[r],fa[t]);
}
}
int read()//读入挂,输入有点多
{
int x=,f=;
char c=getchar();
while((c<'' || c>'') && c!=EOF)
{
if(c=='-') f=-;
c=getchar();
}
while((c<='' && c>='') && c!=EOF)
{
x=x*+c-'';
c=getchar();
}
return x*f;
}
void bfs(int x)//bfs求深度
{
for(int i=; i<a[x].size(); i++)
{
if(b[a[x][i]]==&&a[x][i]!=)
{
fa[a[x][i]]=x;//顺便记录一下父节点
b[a[x][i]]=b[x]+;
rec.push(a[x][i]);
} }
}
int main()
{
n=read();
fa[]=;//attention!
int p,q,cnt=,T,st,en;
for(int i=; i<n; i++)//vector建边
{
p=read();
q=read();
a[p].push_back(q);
a[q].push_back(p);
}
rec.push();
b[]=;//attention!
while(cnt>)
{
p=rec.front();
bfs(p);
rec.pop();
cnt=rec.size();
}
init();
T=read();
while(T--)
{
st=read();
en=read();
k=read();
ans=;
digui(st,en);
printf("%lld\n",ans);
}
return ;
}

求和VII的更多相关文章

  1. 【LCA】求和VII @北京OI2018

    目录 求和VII PROBLEM 题目描述 输入 输出 样例输入 样例输出 提示 SOLUTION CODE 求和VII PROBLEM 时间限制: 2 Sec 内存限制: 256 MB 题目描述 m ...

  2. Java程序:从命令行接收多个数字,求和并输出结果

    一.设计思想:由于命令行接收的是字符串类型,因此应先将字符串类型转化为整型或其他字符型,然后利用for循环求和并输出结果 二.程序流程图: 三.源程序代码:   //王荣荣 2016/9/23     ...

  3. Java之递归求和的两张方法

    方法一: package com.smbea.demo; public class Student { private int sum = 0; /** * 递归求和 * @param num */ ...

  4. EXCEL中对1个单元格中多个数字求和

    如A1=3779.3759.3769.3781.3750,A2对A1中4个数字求和怎么求!请高手赐教! 方法一:在B1中输入公式=SUM(MID(A1,{1,6,11,16,21},4)*1) 方法二 ...

  5. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  6. 从sum()求和引发的思考

    sum()求和是一个非常简单的函数,以前我的写法是这样,我想大部分和我一样刚开始学习JS的同学写出来的也会是这样. function sum() { var total=null; for(var i ...

  7. //给定N个整数序列{A1,A2,A3...An},求函数f(i,j)=(k=i~j)Ak的求和

    //给定N个整数序列{A1,A2,A3...An},求函数f(i,j)=(k=i~j)Ak的求和 # include<stdio.h> void main() { ,sum1; ]={,- ...

  8. Ajax中get请求和post请求

    我们在使用Ajax向服务器发送数据时,可以采用Get方式请求服务器,也可以使用Post方式请求服务器,那么什么时候该采用Get方式,什么时候该采用Post方式呢? Get请求和Post请求的区别: 1 ...

  9. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

随机推荐

  1. centos 7.X关闭防火墙和selinux

    一.关闭防火墙 centos从7开始默认用的是firewalld,这个是基于iptables的,虽然有iptables的核心,但是iptables的服务是没安装的. 所以你只要停止firewalld服 ...

  2. 在 .NET Framework 中使用 StringBuilder 类

    在 .NET Framework 中使用 StringBuilder 类 String 对象是不可变的.每次使用 System.String 类中的一个方法时,都要在内存中创建一个新的字符串对象,这就 ...

  3. 帝都Day4(1)——还是dp

    其实是day4 一.洛谷P1018 乘积最大 f[i][j]表示前i个数 切成j块 用f[i][j]而不用f[i][j][k](i到j切成k块)呢? Luogu1043 前缀和(好算一段里的数的和)+ ...

  4. UnityError 打包到Android错误解决

  5. [原创]Nodejs 远程执行linux shell

    分享几个基于nodejs远程执行linux shell的函数 参数说明: ips - 一个存有IP地址的数组对象 /** * Created by kevalin on 2015/4/27. */ v ...

  6. C# 读写XML文件的方法

    C# 读写XML文件的方法 一.写XML文件 XmlDocument xmlDocument = new XmlDocument();xmlDocument.AppendChild(xmlDocume ...

  7. 记一次序列化的JSON解析问题

    目录 一.问题初探 二.问题原因 三.解决问题 一.问题初探 我今天在使用Ribbon 远程调用的时候 消费者去消费服务端所提供的服务,在使用Post请求中的PostForEntity传递参数的时候, ...

  8. java字符串与二进制的相互转化

    public class StrBinaryTurn { // 将Unicode字符串转换成bool型数组 public boolean[] StrToBool(String input) { boo ...

  9. python 发布

    使用distutils.core.setup函数发布程序 将要发布的包放到mypub的目录下 在mypub目录下创建一个setup.py文件 setup.py文件的设置 from distutils. ...

  10. 扩展(spread)/收集(rest)运算符

    一.扩展运算符(spread)    场景:使用在数组之前. 作用:将一个数组转为用逗号分隔的参数序列 举例1:数组之前 function foo(x, y, z){ console.log(x, y ...