题目

题目

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. pcap中不同包功能

    1.不同包协议的功能 EAPoL:基于局域网的扩展认证协议 ICMPv6:(一般是四个连在一起)互联网控制协议第六套 DHCP Discover:请求分配IP DHCP Offer:你的IP是***, ...

  2. Altera DDR2 IP核学习总结2-----------DDR2 IP核的生成

    打开IP核工具,然后选择Verilog HDL选项,填写路径,写入文件名DDR2_IP.V,点击next PLL reference clock frequency填入板子晶振的频率50MHZ,这里设 ...

  3. php连接mysql,数据CRUD操作

    插入数据 <?php $name = $_GET['username']; $sex = $_GET['sex']; $hobby = $_GET['hobby']; $address = $_ ...

  4. python中用*和**解析数据

    在python中可以用*解析tuple,list,set数据给函数传参,用**解析dict类型数据,这样可使代码更加简洁. 示例代码: def func(a,b,c): print('a:{0},b: ...

  5. C#各种委托介绍

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 一.委托的声明 Delegate Delegate 我们常用到的一种声明 Delegate 至少 ...

  6. Redis配置主从时报错“Could not connect to Redis at 192.168.0.50:6379: Connection refused not connected>”

    配置Redis主从时,修改完从节点配置文件,然后报错 [root@Rich七哥-0-50 redis]# /opt/redis/redis-cli -h 192.168.0.50 Could not ...

  7. 小记---------FLUM负载均衡配置

    sink group允许组织多个sink到一个实体上,sink processors能够提供在组内所有sink之间实现负载均衡的能力,而且在失败的情况下能够进行故障转移从一个sink到另一个sink, ...

  8. Java基础——Modifier类

    转自:https://www.cnblogs.com/baiqiantao/p/7478523.html   反射 Reflect Modifier 修饰符工具类 在查看反射相关的Class.Fiel ...

  9. C++ 调用C语言、extern "C"、__cplusplus关键字

    ——C++编译器完全兼容C语言的编译方式.(但是得有源代码) ——C++编译器会优先使用C++的编译方式进行编译 ——extern "C" 关键字能够强制C++编译器进行C方式的编 ...

  10. (转)终于有人把Elasticsearch原理讲透了!

    终于有人把Elasticsearch原理讲透了! 小史是一个非科班的程序员,虽然学的是电子专业,但是通过自己的努力成功通过了面试,现在要开始迎接新生活了. 来源:互联网侦察 | 2019-04-08 ...