[JZOJ4816]label
来源:互联网 发布:高爆地雷升级数据 编辑:程序博客网 时间:2024/05/21 17:49
题目大意
一棵大小为
求方案数对
一个测试点
题目分析
一个很显然的做法,令
处理前缀和,我们可以在
然而这个做法,弱、逊、水还有naive,是肯定会T的。但是我们能鄙视它吗?不能。
从这个算法继续深入思考。首先可以发现
感性理解(sui bian gao gao)就可以想(cai)到前面一段的长度一定是至多
那么我们直接判断
时间复杂度
代码实现
#include <iostream>#include <cstring>#include <cstdio>#include <cctype>using namespace std;const int P=1000000007;const int N=105;const int K=105;const int S=N*K*2;const int E=N<<1;inline int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}int T,n,m,k,tot,ans,s;int f[N][S],g[N][S];int next[E],tov[E];int last[N],fa[N];void clear(){ memset(f,0,sizeof f); for (;tot;tot--) next[tot]=tov[tot]=0; for (int i=1;i<=n;i++) fa[i]=last[i]=0;}inline void insert(int x,int y){tov[++tot]=y,next[tot]=last[x],last[x]=tot;}inline int sum(int x,int l,int r){return ((g[x][r]-g[x][l-1])%P+P)%P;}void brute(int x){ for (int i=1;i<=m;i++) f[x][i]=1; for (int i=last[x],y;i;i=next[i]) if ((y=tov[i])!=fa[x]) { fa[y]=x,brute(y); for (int j=1;j<=m;j++) f[x][j]=1ll*f[x][j]*((sum(y,min(j+k,m+1),m)+sum(y,1,max(j-k,0)))%P)%P; } for (int i=1;i<=m;i++) g[x][i]=(g[x][i-1]+f[x][i])%P;}void dp(int x){ for (int i=1;i<=s+1;i++) f[x][i]=1; for (int i=last[x],y;i;i=next[i]) if ((y=tov[i])!=fa[x]) { fa[y]=x,dp(y); for (int j=1;j<=s;j++) f[x][j]=1ll*f[x][j]*((((j+k<=m-s?(sum(y,1,s)+1ll*min(m-s-j-k+1,m-s*2)*f[y][s+1]%P)%P:sum(y,1,m-j-k+1))+sum(y,1,max(j-k,0)))%P+(j+k<=s?sum(y,j+k,s):0))%P)%P; if (m-s*2>=1) f[x][s+1]=1ll*f[x][s+1]*(((s+1+k<=m-s?(sum(y,1,s)+1ll*(m-s-s-k)*f[y][s+1]%P)%P:sum(y,1,m-s-k))%P+sum(y,1,max(s+1-k,0)))%P)%P; } for (int i=1;i<=s+1;i++) g[x][i]=(g[x][i-1]+f[x][i])%P;}int main(){ freopen("label.in","r",stdin),freopen("label.out","w",stdout); for (T=read();T--;) { clear(); n=read(),m=read(),k=read(); for (int i=1,x,y;i<n;i++) x=read(),y=read(),insert(x,y),insert(y,x); if (!k) { ans=1; for (int i=1;i<=n;i++) ans=1ll*ans*m%P; } else if (m<=(s=(n-1)*k)*2) { brute(1); ans=0; for (int i=1;i<=m;i++) (ans+=f[1][i])%=P; } else { dp(1); ans=0; for (int i=1;i<=s;i++) (ans+=f[1][i]*2%P)%=P; (ans+=1ll*(m-s*2)*f[1][s+1]%P)%=P; } printf("%d\n",ans); } fclose(stdin),fclose(stdout); return 0;}
0 0
- [JZOJ4816]label
- 【JZOJ4816】label
- JZOJ4816. label
- NOIP提高组【JZOJ4816】label
- 【JZOJ4816】【NOIP2016提高A组五校联考4】label
- label
- Label
- label
- Label
- label
- Label
- label
- label
- label
- Label
- label
- label 调整label高度
- Label字体大小自适应label
- Python print线程安全
- 排队
- SQL 之 模糊匹配
- JZOJ 4814 【NOIP2016提高A组五校联考2】tree
- string
- [JZOJ4816]label
- 二叉树的中序非递归遍历c语言版
- running
- tree
- 【NOIP2016提高A组五校联考1】挖金矿
- java多线程常用方法区别--备忘笔记
- 面向对象设计原则
- 获取http的gzip内容并解压相关问题(续)
- eclipse Access restriction required library rt.jar