题目描述

master 对树上的求和非常感兴趣。他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的 kkk 次方和,而且每次的 kkk 可能是不同的。此处节点深度的定义是这个节点到根的路径上的边数。他把这个问题交给了pupil,但pupil 并不会这么复杂的操作,你能帮他解决吗?

输入输出格式

输入格式:

第一行包含一个正整数 nnn ,表示树的节点数。

之后 n−1n-1n−1 行每行两个空格隔开的正整数 i,ji, ji,j ,表示树上的一条连接点 iii 和点 jjj 的边。

之后一行一个正整数 mmm ,表示询问的数量。

之后每行三个空格隔开的正整数 i,j,ki, j, ki,j,k ,表示询问从点 iii 到点 jjj 的路径上所有节点深度的 kkk 次方和。由于这个结果可能非常大,输出其对 998244353998244353998244353 取模的结果。

树的节点从 111 开始标号,其中 111 号节点为树的根。

输出格式:

对于每组数据输出一行一个正整数表示取模后的结果。

输入输出样例

输入样例#1:
复制

5
1 2
1 3
2 4
2 5
2
1 4 5
5 4 45
输出样例#1: 复制

33
503245989

说明

样例解释

以下用 d(i)d (i)d(i) 表示第 iii 个节点的深度。

对于样例中的树,有 d(1)=0,d(2)=1,d(3)=1,d(4)=2,d(5)=2d (1) = 0, d (2) = 1, d (3) = 1, d (4) = 2, d (5) = 2d(1)=0,d(2)=1,d(3)=1,d(4)=2,d(5)=2 。

因此第一个询问答案为 (25+15+05) mod 998244353=33(2^5 + 1^5 + 0^5)\ mod\ 998244353 = 33(25+15+05) mod 998244353=33 ,第二个询问答案为 (245+145+245) mod 998244353=503245989(2^{45} + 1^{45} + 2^{45})\ mod\ 998244353 = 503245989(245+145+245) mod 998244353=503245989 。

数据范围

对于 30%30\%30% 的数据, 1≤n,m≤1001 \leq n,m \leq 1001≤n,m≤100 。

对于 60%60\%60% 的数据, 1≤n,m≤10001 \leq n,m \leq 10001≤n,m≤1000 。

对于 100%100\%100% 的数据, 1≤n,m≤300000,1≤k≤501 \leq n,m \leq 300000, 1 \leq k \leq 501≤n,m≤300000,1≤k≤50 。

另外存在5个不计分的hack数据

提示

数据规模较大,请注意使用较快速的输入输出方式。


先抱怨一波好吧,
  bjoi多么良心,出了那么多数据结构,mmp,再看看hnoi,woc,真的不要脸
  所以我这种菜鸡就只能打一打树剖这种傻逼题来泄愤了
 
题解:
 
  1)50次方,就是把每一个次方的值建一个线段树,后面就可以直接询问了
  2)取mod是一个很玄学的东西
  3)注意一下空间
  4)所有树剖题目都是一个思路,不难想但是难调
 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=;
const int mod=;
int n,m,dep[][N],fa[N],size[N],son[N],maxx,fid[N];
int l[N],tot,head[N*],num,top[N];
struct node{
int to,next;
}e[N*];
struct tr{
int sum[N*];
}t[];
int read()
{
int x=,w=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*w;
} void add(int from,int to)
{
num++;
e[num].to=to;
e[num].next=head[from];
head[from]=num;
} void dfs1(int x)
{
size[x]=;
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(!dep[][v]&&v!=)
{
dep[][v]=dep[][x]+;fa[v]=x;
maxx=max(maxx,dep[][v]);
dfs1(v);
size[x]+=size[v];
if(size[v]>size[son[x]])son[x]=v;
}
}
} void dfs2(int x,int tp)
{
l[x]=++tot;top[x]=tp;fid[tot]=x;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa[x]&&v!=son[x])
dfs2(v,v);
}
} void init()
{
n=read();
for(int i=;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
dfs1();
dep[][]=;fa[]=;
dfs2(,);
} void build(int rt,int root,int left,int right)
{ if(left==right){
t[rt].sum[root]=dep[rt][fid[left]];
return ;
}
int mid=(left+right)>>;
build(rt,root<<,left,mid);
build(rt,root<<|,mid+,right);
t[rt].sum[root]=(ll)(t[rt].sum[root<<]+t[rt].sum[root<<|])%mod;
if(t[rt].sum[root]>=mod)t[rt].sum[root]-=mod;
} int query(int rt,int root,int left,int right,int L,int R)
{
if(left>R||right<L)return ;
if(L<=left&&right<=R)return t[rt].sum[root]%mod;
int mid=(left+right)>>;
ll a=,b=;
if(mid>=L)a=query(rt,root<<,left,mid,L,R)%mod;
if(mid<R) b=query(rt,root<<|,mid+,right,L,R)%mod;
return (a+b)%mod;
} int cal(int rt,int x,int y)
{
ll ans=;
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]<dep[fy]){swap(fx,fy);swap(x,y);}
ans+=query(rt,,,n,l[fx],l[x]);
ans%=mod;
x=fa[fx],fx=top[x];
}
if(l[x]>l[y])swap(x,y);
ans+=query(rt,,,n,l[x],l[y]);
ans%=mod;
return ans;
} void perp()
{
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
{dep[i][j]=((ll)dep[i-][j]%mod*(ll)dep[][j]%mod)%mod;}
for(int i=;i<=;i++)
build(i,,,n);
} void solve()
{
m=read();
for(int i=;i<=m;i++)
{int x=read(),y=read(),k=read();
printf("%d\n",cal(k,x,y));}
} int main()
{
init();
perp();
solve();
return ;
}

[BJOI2018]求和(树链剖分)的更多相关文章

  1. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  2. BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分+单点更新+区间求和+区间求最大值)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题意:略. 题解:树链剖分模版,注意一些细节即可. #include <ios ...

  3. 树链剖分好(du)题(liu)选做

    1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...

  4. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  5. 树链剖分(+线段树)(codevs4633)

    type node=^link; link=record des:longint; next:node; end; type seg=record z,y,lc,rc,toadd,sum:longin ...

  6. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  7. BZOJ 1036 树的统计-树链剖分

    [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12904 Solved: 5191[Submit][Status ...

  8. 树分治&树链剖分相关题目讨论

    预备知识 树分治,树链剖分   poj1741 •一棵有n个节点的树,节点之间的边有长度.方方方想知道,有多少个点对距离不超过m 题解 点分治模板题.详见我早上写的http://www.cnblogs ...

  9. 树链剖分||dfs序 各种题

    1.[bzoj4034][HAOI2015]T2 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把 ...

  10. FZU 2082 过路费 (树链剖分 修改单边权)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...

随机推荐

  1. 51nod 1448 二染色问题 (逆向考虑)

    题目: 注意,这题不是把一块区域的黑翻成白.白翻成黑. 是把一块区域全部翻成白或者翻成黑. 初始为全白,看能否翻出题中的情况. 我们假设翻转若干次能得到图中的形状,那么我们找出最后一次的翻转,即全W或 ...

  2. RabbitMQ笔记(3)

    消息从产生--->结束 1.生产者--->交换机--->队列--->消费者 2.生产者--->交换机--->队列 首先: 生产者:Exchange = n:1 Ex ...

  3. springmvc_learn

    https://blog.csdn.net/qq598535550/article/details/51703190 https://github.com/wosyingjun/beauty_ssm

  4. HDU 1556 Color the ball【树状数组】

    题意:给出n个区间,每次给这个区间里面的数加1,询问单点的值 一维的区间更新,单点查询,还是那篇论文里面讲了的 #include<iostream> #include<cstdio& ...

  5. SpringBoot学习笔记(12)----SpringBoot实现多个 账号轮询发送邮件

    首先,引入发送邮件的依赖,由于freemarker自定义模板,所以也需要把freemarker的依赖引入 pom.xml文件 <dependency> <groupId>org ...

  6. Artisan 命令

    php artisan key:generate 生成 App Key php artisan make:controller 生成控制器 php artisan make:model 生成模型 ph ...

  7. PCA一些性质的定性理解

    1.通过本征向量和本征值求主成分 关系:本征值是本征向量的缩放倍数,本征值大的对应的本征向量上的样本的数目就越多:相反本征值越小的,就本征向量上的样本数量就会少.因此可以求出PCA的主成分 主成分分析 ...

  8. 单机Mongo复制集安装配置(数据库版本:4.x)

      官方文档: https://docs.mongodb.com/manual/tutorial/deploy-replica-set-with-keyfile-access-control/#dep ...

  9. Eclipse配置class文件输出目录

    1, Eclipse选中项目名称,邮件选中“Build Path”,然后选择“Configure Build Path”--->选择“Source” Tab---->修改"Def ...

  10. Python seed() 函数--每次产生一样的随机数系列

    import random random.seed( 10 ) print("Random number with seed 10 : ", random.random()) #0 ...