C:显然可以设f[i][S]为当前考虑到第i位,[i,i+k)的状态为S的最小能量消耗,这样直接dp是O(nC(k,x))的。考虑矩阵快速幂,构造min+转移矩阵即可,每次转移到下一个特殊点然后暴力处理掉该点的贡献。可以预处理2p次转移矩阵进一步加速。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<map>
  8. using namespace std;
  9. #define ll long long
  10. #define N 80
  11. #define inf 1000000000000000000ll
  12. char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
  13. int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
  14. int read()
  15. {
  16. int x=0,f=1;char c=getchar();
  17. while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
  18. while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
  19. return x*f;
  20. }
  21. int n,m,k,q,c[10],id[1<<8],t;
  22. map<int,int> d;
  23. struct data
  24. {
  25. int x,y;
  26. bool operator <(const data&a) const
  27. {
  28. return x<a.x;
  29. }
  30. }p[30];
  31. struct matrix
  32. {
  33. int n;ll a[N][N];
  34. matrix operator *(const matrix&b) const
  35. {
  36. matrix c;c.n=n;for (int i=0;i<n;i++) for (int j=0;j<b.n;j++) c.a[i][j]=inf;
  37. for (int i=0;i<n;i++)
  38. for (int j=0;j<b.n;j++)
  39. for (int k=0;k<b.n;k++)
  40. c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
  41. return c;
  42. }
  43. }f,a,g;
  44. matrix power(matrix a,int k)
  45. {
  46. matrix c;c.n=a.n;
  47. for (int i=0;i<t;i++)
  48. for (int j=0;j<t;j++)
  49. c.a[i][j]=inf;
  50. for (int i=0;i<t;i++) c.a[i][i]=0;
  51. for (;k;k>>=1,a=a*a) if (k&1) c=c*a;
  52. return c;
  53. }
  54. signed main()
  55. {
  56. #ifndef ONLINE_JUDGE
  57. freopen("c.in","r",stdin);
  58. freopen("c.out","w",stdout);
  59. #endif
  60. n=read(),m=read(),k=read(),q=read();
  61. for (int i=1;i<=m;i++) c[i]=read();
  62. for (int i=1;i<=q;i++) p[i].x=read(),p[i].y=read(),d[p[i].x]=p[i].y;
  63. sort(p+1,p+q+1);
  64. memset(id,255,sizeof(id));
  65. for (int i=0;i<(1<<m);i++)
  66. {
  67. int cnt=0,j=i;while (j) j^=j&-j,cnt++;
  68. if (cnt==n) id[i]=t++;
  69. }
  70. a.n=t;
  71. for (int i=0;i<t;i++)
  72. for (int j=0;j<t;j++)
  73. a.a[i][j]=inf;
  74. for (int i=0;i<(1<<m);i++)
  75. if (id[i]>=0)
  76. {
  77. if (i&1)
  78. {
  79. for (int x=1;x<=m;x++)
  80. if (!(i&(1<<x))) a.a[id[i]][id[(i|(1<<x))>>1]]=c[x];
  81. }
  82. else a.a[id[i]][id[i>>1]]=0;
  83. }
  84. f.n=1;for (int i=0;i<t;i++) f.a[0][i]=inf;f.a[0][id[(1<<n)-1]]=0;
  85. int cur=1;
  86. for (int i=1;i<=q;i++)
  87. {
  88. if (p[i].x-10>=cur) f=f*power(a,p[i].x-10-cur),cur=p[i].x-10;
  89. int u=i;while (u<q&&p[u+1].x-p[u].x<=10) u++;
  90. while (cur<p[u].x&&cur<k-n+1)
  91. {
  92. g.n=1;for (int x=0;x<t;x++) g.a[0][x]=inf;
  93. for (int j=0;j<(1<<m);j++)
  94. if (id[j]>=0)
  95. {
  96. if (j&1)
  97. {
  98. for (int x=1;x<=m;x++)
  99. if (!(j&(1<<x))) g.a[0][id[(j|(1<<x))>>1]]=min(g.a[0][id[(j|(1<<x))>>1]],f.a[0][id[j]]+c[x]+d[cur+x]);
  100. }
  101. else g.a[0][id[j>>1]]=min(g.a[0][id[j>>1]],f.a[0][id[j]]);
  102. }
  103. f=g;
  104. cur++;
  105. }
  106. i=u;
  107. }
  108. f=f*power(a,k-n-cur+1);
  109. cout<<f.a[0][id[(1<<n)-1]];
  110. return 0;
  111. //NOTICE LONG LONG!!!!!
  112. }

  D:首先考虑如果我们钦定了其中k条边一定在树中,有多少种方案。可以把每个连通分量缩点,将其权值定义为其大小,将一条边的权值定义为其两端的点权值之积,将一棵树的权值定义为所有边权值之积,显然这样缩点后所有树的权值之和,就是钦定这些边后原树的数量。

  注意到上述树权值的定义等价于∏每个点的权值度数。既然出现了度数,考虑与度数关系密切的prufer序列。我们知道prufer序列中每个点的出现次数=其度数-1,所以对于某一种prufer序列,其对应的树的权值是所有点权值之积*prufer序列每个点权值之积。由于我们要求所有树的权值之和,而所有树对应着所有的prufer序列,由乘法分配律可得,这个东西就是所有点权值之积*n点数-2,其中n是原树点的个数。这样就可以知道钦定了边的方案数了。

  然后考虑对所有钦定k条边的情况求和,这样容斥一发就能求出恰有k条边的方案数。显然我们只需要求出所有方案的所有点权值之积的和,可以做一个树上二维背包,即f[i][j][k]为i子树钦定了j条边,根所在连通块大小为k时,子树内所有内连通块大小之积的和。由于对子树大小取min,复杂度是O(n4)。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<cassert>
  8. using namespace std;
  9. #define ll long long
  10. #define N 110
  11. #define P 1000000007
  12. char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
  13. int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
  14. int read()
  15. {
  16. int x=0,f=1;char c=getchar();
  17. while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
  18. while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
  19. return x*f;
  20. }
  21. int n,k,p[N],f[N][N][N],g[N][N],h[N][N],C[N][N],size[N],inv[N],t,root=1;
  22. struct data{int to,nxt;
  23. }edge[N<<1];
  24. void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
  25. int ksm(int a,int k)
  26. {
  27. int s=1;
  28. for (;k;k>>=1,a=1ll*a*a%P) if (k&1) s=1ll*s*a%P;
  29. return s;
  30. }
  31. void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
  32. void dfs(int k,int from)
  33. {
  34. size[k]=1;f[k][0][1]=1;
  35. for (int i=p[k];i;i=edge[i].nxt)
  36. if (edge[i].to!=from)
  37. {
  38. int x=edge[i].to;
  39. dfs(x,k);
  40. for (int u=0;u<size[k]+size[x];u++)
  41. for (int s=0;s<=u+1;s++)
  42. g[u][s]=f[k][u][s],f[k][u][s]=0;
  43. for (int u=0;u<size[k]+size[x];u++)
  44. for (int s=1;s<=u+1;s++)
  45. for (int v=max(0,u-size[k]);v<=min(u,size[x]);v++)
  46. {
  47. inc(f[k][u][s],1ll*g[u-v][s]*h[x][v]%P);
  48. if (u>v)
  49. for (int t=max(1,s-(u+1));t<=min(s,v+1);t++)
  50. inc(f[k][u][s],1ll*g[u-v-1][s-t]*inv[s-t]%P*f[x][v][t]%P*inv[t]%P*s%P);
  51. }
  52. size[k]+=size[x];
  53. }
  54. for (int i=0;i<size[k];i++)
  55. for (int j=1;j<=i+1;j++)
  56. inc(h[k][i],f[k][i][j]);
  57. }
  58. int calc(int k)
  59. {
  60. int ans=0;
  61. for (int i=k;i<n;i++)
  62. {
  63. int x=h[root][i];
  64. if (i==n-1) x=1;else x=1ll*x*ksm(n,n-2-i)%P;
  65. x=1ll*x*C[i][k]%P;
  66. if (i-k&1) ans=(ans-x+P)%P;else ans=(ans+x)%P;
  67. }
  68. return ans;
  69. }
  70. int main()
  71. {
  72. n=read();
  73. for (int i=1;i<n;i++)
  74. {
  75. int x=read(),y=read();
  76. addedge(x,y),addedge(y,x);
  77. }
  78. C[0][0]=1;
  79. for (int i=1;i<=n;i++)
  80. {
  81. C[i][0]=C[i][i]=1;
  82. for (int j=1;j<i;j++)
  83. C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
  84. }
  85. for (int i=1;i<=n;i++) inv[i]=ksm(i,P-2);
  86. dfs(root,root);
  87. for (int i=0;i<n;i++) printf("%d ",calc(i));
  88. return 0;
  89. }

  

Codeforces Round #459 Div. 1的更多相关文章

  1. Codeforces Round #459 (Div. 2)

    A. Eleven time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  2. Codeforces Round #459 (Div. 2) D. MADMAX DFS+博弈

    D. MADMAX time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  3. Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)

    D. MADMAX time limit per test1 second memory limit per test256 megabytes Problem Description As we a ...

  4. Codeforces Round #459 (Div. 2):B. Radio Station

    B. Radio Station time limit per test2 seconds memory limit per test256 megabytes Problem Dsecription ...

  5. Codeforces Round #459 (Div. 2)-A. Eleven

    A. Eleven time limit per test1 second memory limit per test256 megabytes Problem Description Eleven ...

  6. Codeforces Round #459 (Div. 2):D. MADMAX(记忆化搜索+博弈论)

    题意 在一个有向无环图上,两个人分别从一个点出发,两人轮流从当前点沿着某条边移动,要求经过的边权不小于上一轮对方经过的边权(ASCII码),如果一方不能移动,则判负.两人都采取最优策略,求两人分别从每 ...

  7. Codeforces Round #459 (Div. 2)The Monster[匹配问题]

    题意 给一个序列,包含(,),?,?可以被当做(或者),问你这个序列有多少合法的子序列. 分析 n^2枚举每一个子序列,暂时将每个?都当做右括号,在枚举右端点的时候同时记录两个信息:当前左括号多余多少 ...

  8. Codeforces Round #459 (Div. 2)C. The Monster

    C. The Monster time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. 【Codeforces Round #459 (Div. 2) B】 Radio Station

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用map模拟一下映射就好了. [代码] #include <bits/stdc++.h> using namespace ...

随机推荐

  1. Mac 小记 — iTerm2、Zsh、Homebrew

    前言 写完 "Ubuntu 自动化配置" 这篇文章后,每次连服务器心情指数都上升好几个百分点,于是想着应该将 macOs 的开发环境也梳理梳理,应该会对开发效率有所增益. 1. i ...

  2. 使用模块PIL 生成 随机验证码

    --------------默认自己无能,无疑是给失败制造机会!你认为自己是什么样的人,就将成为什么样的人. 要使用PIL模块. 安装: 1 pip3 install pillow 基本使用 1. 创 ...

  3. Quartz-Spring定时任务器持久化,通过Service动态添加,删除,启动暂停任务

    原文地址:https://blog.csdn.net/ljqwstc/article/details/78257091 首先添加maven的依赖: <!--quartz定时任务--> &l ...

  4. Leetcode 665. Non-decreasing Array(Easy)

    Given an array with n integers, your task is to check if it could become non-decreasing by modifying ...

  5. Tea Party CodeForces - 808C (构造+贪心)

    Polycarp invited all his friends to the tea party to celebrate the holiday. He has ncups, one for ea ...

  6. 使用mysql,sql语言删除冗余信息

    这是表,我们需要操作的就是删除除了学号不同,其它信息都相同的冗余信息 思路:删除表格class3中的冗余的stu_id信息,那么接下来我们应该去筛选哪些stu_id信息是冗余的, 此时我们想到的就是利 ...

  7. 学习mongoDB的一些感受(转自:http://blog.csdn.net/liusong0605/article/details/11581019)

    曾经使用过mongoDB来保存文件,最一开始,只是想总结一下在开发中如何实现文件与mongoDB之间的交互.在此之前,并没有系统的了解过mongoDB,虽然知道我们用它来存储文件这些非结构化数据,但是 ...

  8. python 实现快速排序

    一.快排思想 快速排序可以理解为是对冒泡排序的一种改进,把一组数,按照初始选定的标杆(参照数), 分别从两端开始排序,左端'i'只要小于标杆(参照数)的数,右端'j'只要大于标杆(参照数)的数, i- ...

  9. JS_左边栏菜单

    需求: 要求实现左边栏菜单点击一下就弹开,其他的隐藏.再点击一下就隐藏. 最多只能有一个菜单的详细内容会显示出来. 三个菜单实现联动效果. 代码如下: 1 <!DOCTYPE html> ...

  10. window端编码到Linux允许脚本 笔记

    昨天升级一个服务,发现没有现成的启动脚本.就随手写了一个,一运行发现不行.竟然报错说找不到文件,No such file or directory [nohup: cannot run command ...