题目

题目

20%算法

设\(f_{i,j}\)表示第i个节点选了j这个权值的方案数。

显然转移方程为,$$f_{i,j}=\Pi_{v=son(i)}(\sum_{k=1}{j-k}f_{v,k}+\sum_{k=j+k}{m}f_{v,k})$$

40%算法

接着上面的想法,

观察转移方程,发现,求和部分其实是两段连续的,那么将\(f_{i}\)求一个前缀和。

100%算法

观察\(f\)数组,发现其实\(f\)是对称的,而且中间的一段是相同的,设深度为x,那么前面就有\((x-1)k\)个不同,然后中间有一段相同,后面又有\((x-1)k\)个不同。

那么就可以只求出前\((x-1)k+1\)个,前缀和就可以直接算出来(程序中我直接求出前10010个的值,没有计算x)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=1000000007;
const long long N=105;
using namespace std;
long long f[N][N*N*2],_,n,m,k,next[N*2],last[N*2],to[N*2],tot,same[N],sum1[N][N*N],sum2[N][N*N];
long long pos[N];
long long max(long long x,long long y)
{
if(x<y) return y;else return x;
}
long long min(long long x,long long y)
{
if(x>y) return y;else return x;
}
long long bj(long long x,long long y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
long long sum(int x,int y)
{
if(y<=10010) return sum1[x][y];
else
if(y<m-pos[x]+1)
{
return (sum1[x][pos[x]]+same[x]*(y-pos[x])%mo)%mo;
}
else
{
return (sum1[x][pos[x]]+(m-pos[x]-pos[x])*same[x]%mo+sum2[x][(y-(m-pos[x]))])%mo;
}
}
long long dg(long long x,long long fa)
{
bool q=false;
for(long long i=last[x];i;i=next[i])
{
long long j=to[i];
if(j!=fa)
{
dg(j,x);
q=true;
}
}
for(long long i=1;i<=min(10010,m);i++) f[x][i]=1;
for(long long i=last[x];i;i=next[i])
{
long long j=to[i];
if(j!=fa)
{
for(long long l=1;l<=min(10010,m);l++)
{
long long t=0;
t=(t+(sum(j,max(0,l-k))-sum(j,0)+mo))%mo;
if(l+k<=m)
{
t=(t+(sum(j,m)-sum(j,l+k-1)+mo))%mo;
if(max(0,l-k)==l+k)
t=(t-f[j][l+k]+mo)%mo;
}
f[x][l]=(f[x][l]*t)%mo;
}
}
}
if(10010<m)
{
for(int i=1;i<=10010;i++)
{
if(f[x][i]==f[x][i+1])
{
same[x]=f[x][i];
pos[x]=i-1;
break;
}
}
}
else
{
same[x]=f[x][m/2];
}
for(int i=1;i<=min(10010,m);i++)
sum1[x][i]=(sum1[x][i-1]+f[x][i])%mo;
for(int i=1;i<=min(10010,m);i++)
sum2[x][i]=(sum2[x][i-1]+f[x][pos[x]-i+1])%mo;
}
int main()
{
scanf("%lld",&_);
while(_--)
{
scanf("%lld%lld%lld",&n,&m,&k);
memset(f,0,sizeof(f));
memset(last,0,sizeof(last));
memset(next,0,sizeof(next));
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
memset(pos,0,sizeof(pos));
tot=0;
for(long long i=1;i<=n-1;i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
bj(x,y);
bj(y,x);
}
dg(1,0);
printf("%lld\n",sum(1,m));
}
}

【NOIP2016提高A组五校联考4】label的更多相关文章

  1. NOIP2016提高A组五校联考4总结

    坑爹的第一题,我居然想了足足3个小时,而且还不确定是否正确. 于是,我就在这种情况下心惊胆跳的打了,好在ac了,否则就爆零了. 第二题,树形dp,本来差点就想到了正解,结果时间不够,没打完. 第三题, ...

  2. 【NOIP2016提高A组五校联考4】square

    题目 分析 首先,设\(f_{i,j}\)表示最大的以(i,j)为左下角的正方形的边长. 转移显然,\(f_{i,j}=\max(f_{i-1,j},f_{i,j-1},f_{i-1,j-1})+1\ ...

  3. 【NOIP2016提高A组五校联考4】ksum

    题目 分析 发现,当子段[l,r]被取了出来,那么[l-1,r].[l,r+1]一定也被取了出来. 那么,首先将[1,n]放入大顶堆,每次将堆顶的子段[l,r]取出来,因为它是堆顶,所以一定是最大的子 ...

  4. NOIP2016提高A组五校联考3总结

    第一题,本来一开始就想到了数位dp,结果脑残地打了十几个转移方程,总是调试不出来,一气之下放弃了. 调第一题几乎调了整节比赛,第二第三都没它. 第二题连边找联通块. 第三题题解都打了三页,看都不想看. ...

  5. 【NOIP2016提高A组五校联考2】tree

    题目 给一棵n 个结点的有根树,结点由1 到n 标号,根结点的标号为1.每个结点上有一个物品,第i 个结点上的物品价值为vi. 你需要从所有结点中选出若干个结点,使得对于任意一个被选中的结点,其到根的 ...

  6. 【NOIP2016提高A组五校联考2】running

    题目 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由n个格子排成的一个环形,格子按照顺时针顺序从0 到n- 1 标号. 小胡观察到有m 个同学在跑步,最开始每 ...

  7. 【NOIP2016提高A组五校联考2】string

    题目 给出一个长度为n, 由小写英文字母组成的字符串S, 求在所有由小写英文字母组成且长度为n 且恰好有k 位与S 不同的字符串中,给定字符串T 按照字典序排在第几位. 由于答案可能很大,模10^9 ...

  8. NOIP2016提高A组五校联考2总结

    第一题用组合数各种乱搞,其恶心程度不一般.搞了很久才调对,比赛上出了一点bug,只拿了30分. 第二题我乱搞得出个错误的结论,本来自信满满60分,结果爆零了. 第三题,树形dp,在一开始的时候想到了, ...

  9. NOIP2016提高A组五校联考1总结

    第一题二分,在比赛上明明想到的方法,结果考虑的时候似乎漏了什么,被否决掉了. 只打了个水法,10分. 第二题,最长不上升子序列,原题,类似的题目做过两道,直接搞定. 第三题,一开始想了一种通过在树上打 ...

随机推荐

  1. windows 快捷键 部分

    1.快速启动任务栏锁定的任务 WIN+任务栏任务顺序(左侧开始数) 2.运行 WIN+R mstsc--->远程桌面链接 regedit--->注册表信息 services.msc---& ...

  2. Python+requests+excel接口测试

    2018-06-14   17:00:13 环境准备: - Python 3.7 - requests库 - xlrd 1.创建Excel文件 2.读取Excel文件 import xlrd clas ...

  3. HCL试验2

    PC端配置:配置ip地址 交换机1配置:①创建VLAN system-view vlan 10 vlan 20 ②配置PC端接口 interface gi 1/0/1 port link-type a ...

  4. A1139-引爆炸弹 计蒜客 bfs剪枝

    题目链接 https://nanti.jisuanke.com/t/A1139 在一个 n \times mn×m 的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上 ...

  5. 第八周课程总结&实验报告

    实验六 Java异常 •实验目的 •理解异常的基本概念: •掌握异常处理方法及熟悉常见异常的捕获方法. • 实验要求 •练习捕获异常.声明异常.抛出异常的方法.熟悉try和catch子句的使用. •掌 ...

  6. HDU 2100 Lovekey (26进制大数、字符串)

    Lovekey Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  7. 普通帐号起redis

    wget http://download.redis.io/releases/redis-4.0.11.tar.gz $ tar xzf redis-4.0.11.tar.gzmv redis-4.0 ...

  8. Linux下面MariaDB 管理命令基础使用

    MariaDB 是 MySQL 的一个分,由于某些原因,使之取代了Mysql成为了 RHEL/CentOS 7 的默认数据库.针对数据库的操作我们经常做的操作就是增删查改,接下来就介绍下 MariaD ...

  9. Android事件监听(一)——简介篇

    Button.ImageButton事件 setOnClickListener     点击时触发 ListView事件 setOnItemSelectedListener   鼠标滚动时触发 set ...

  10. tree_cuttting(树形dp求解树的重心)

    Tree Cutting After Farmer John realized that Bessie had installed a "tree-shaped" network ...