题目描述

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. SpringCloud学习笔记(11)----Spring Cloud Netflix之Hystrix断路器的使用

    为什么会有断路器? 在微服务架构中,系 是拆分成 一个的服务单元各间通过注册与发现 的方式互相依 赖.每个单元都在不同的进程中运行, 都是通过远程调用的方式进行信 ,这样就有可能因为网络原或 是依赖服 ...

  2. C语言的常用printf打印占位符%d, %u, %f, %s, %c, %o, %x

    占位符含义及用法 代码: #include <stdio.h> int main(int argc, char const *argv[]) { , b = -; // 默认10进制赋值 ...

  3. POJ-3159 Candies 最短路应用(差分约束)

    题目链接:https://cn.vjudge.net/problem/POJ-3159 题意 给出一组不等式 求第一个变量和最后一个变量可能的最大差值 数据保证有解 思路 一个不等式a-b<=c ...

  4. 用shell写一个简单DHCP配置脚本

    轩轩写的这个小脚本,主要是可以进行对dhcp服务的安装.简单配置.开启.关闭/查看状态等情况 使用呢非常简单,按照步骤进行准确的设置就可以啦 #!/bin/bashyum -y install dhc ...

  5. vue路由知识整理

    vue路由知识整理 对于单页应用,官方提供了vue-router进行路由跳转的处理.我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(compo ...

  6. Python学习第二天-编写购物车

    需求:1.启动程序后,让用户输入工资,然后打印商品列表         2.允许用户根据商品编号购买商品         3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒          ...

  7. 从头认识java-18.6 synchronized在其它对象上同步和ThreadLocal来消除共享对象的同步问题

    这一章节我们来介绍在其它对象上同步与ThreadLocal. 前一章节我们使用了 1.synchronized在其它对象上同步 class ThreadA implements Runnable { ...

  8. Ruby创建命令

    Ruby创建命令

  9. nyoj--49--开心的小明(背包)

    开心的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 小明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他 ...

  10. rest_framework(解析器 上)

    rest_framework 解析器 对请求题数据进行解析 url from django.conf.urls import url,include from cmdb import views ur ...