bzoj 1494: [NOI2007]生成树计数
来源:互联网 发布:配音软件 语气 编辑:程序博客网 时间:2024/05/16 19:31
55555555555555555555555555555555被虐哭了
调了两个小时才调出来,简直不要太坑。
论文还是比较良心的,就是初始矩阵好难构造的说。
最后迫不得已写了个很挫的方法构造。
#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;typedef long long ll;const int p=65521;const int inf=1e9;int m;struct matrix{ll a[55][55];matrix(){memset(a,0,sizeof(a));}matrix operator * (const matrix &b)const{static matrix ans;memset(ans.a,0,sizeof(ans.a));for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)for(int k=1;k<=m;k++)ans.a[i][j]+=a[i][k]*b.a[k][j];for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)ans.a[i][j]%=p;return ans;}matrix operator ^ (const ll &k)const{static matrix ans,b;memcpy(b.a,a,sizeof(a));for(int i=1;i<=m;i++)ans.a[i][i]=1;ll h=k;for(;h;h>>=1,b=b*b)if(h&1)ans=ans*b;return ans;}};int pa[6],s[55][6];int k;void dfs(int i,int tot){if(i>k){m++;memcpy(s[m],pa,sizeof(pa));}else{for(int j=1;j<=tot;j++){pa[i]=j;dfs(i+1,tot);}pa[i]=tot+1;dfs(i+1,tot+1);}}int size(int i,int j){int sz=0;for(int t=1;t<=k;t++)sz+=s[i][t]==j;return sz;}bool same(int i,int j,int k){return s[k][i]==s[k][j];}int mul(int a,int b){int ans=1;for(int i=1;i<=b;i++)ans*=a; return ans;}int size(int i){int ans=0;for(int j=1;j<=k;j++)ans=max(ans,s[i][j]);return ans;}int calc(int i){int sz=size(i),ans=1;for(int j=1;j<=sz;j++)ans=ans*mul(size(i,j),size(i,j)-2);return ans;}bool check(int pa1[6],int pa2[6]){for(int i=1;i<=k;i++)if(pa1[i]!=pa2[i])return false;return true;}int find(int pa[6]){for(int i=1;i<=m;i++)if(check(pa,s[i]))return i;}bool check(int s,int t){for(int i=1;i<=k;i++)for(int j=i+1;j<=k;j++)if(same(i,j,t)&&(s&(1<<i-1))&&(s&(1<<j-1)))return false;return true;}matrix trans;ll f[55];int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);ll n;scanf("%d%lld",&k,&n);dfs(1,0);for(int i=1;i<=m;i++){int pa[6];for(int state=0;state<(1<<k);state++){if(size(i,1)==1&&(!(state&(1<<0))))continue;if(!check(state,i))continue;memset(pa,0,sizeof(pa));int g[7][7];memset(g,0,sizeof(g));for(int j=1;j<=k;j++)for(int h=j+1;h<=k;h++)if(same(j,h,i))g[j][h]=g[h][j]=1;for(int j=1;j<=k;j++)if(state&(1<<j-1))g[k+1][j]=g[j][k+1]=1;for(int c=1;c<=k+1;c++)for(int a=1;a<=k+1;a++)for(int b=1;b<=k+1;b++)if(g[a][c]&&g[c][b])g[a][b]=1;int tot=0;for(int j=2;j<=k+1;j++){int h;for(h=2;h<j;h++)if(g[j][h])break;if(j==h)pa[j-1]=++tot;else pa[j-1]=pa[h-1];}int t=find(pa);trans.a[i][t]++;}}for(int i=1;i<=m;i++)f[i]=calc(i);trans=trans^(n-k);ll ans=0;for(int i=1;i<=m;i++)ans=(ans+f[i]*trans.a[i][1])%p;printf("%lld\n",ans);return 0;}
0 0
- BZOJ 1494: [NOI2007]生成树计数
- bzoj 1494: [NOI2007]生成树计数
- BZOJ 1494 [NOI2007]生成树计数
- BZOJ 1494 NOI2007 生成树计数 状压DP+矩阵乘法
- 生成树计数 NOI2007
- bzoj1494: [NOI2007]生成树计数
- 【noi2007】生成树计数 连通性DP
- 【基于连通性的状态压缩DP】【NOI2007】生成树计数
- [NOI2007]生成树计数(状压dp+矩阵加速)
- 【BZOJ 1016】 [JSOI2008]最小生成树计数
- BZOJ 1016: [JSOI2008]最小生成树计数
- BZOJ 1016 最小生成树计数 Kruskal
- 最小生成树计数 bzoj 1016
- BZOJ 1016 [JSOI2008]最小生成树计数
- BZOJ 1016,1543 最小生成树计数
- BZOJ 1016, 最小生成树计数
- BZOJ 1016 [JSOI2008] 最小生成树计数
- [BZOJ]1016: [JSOI2008]最小生成树计数
- undefined reference to `__imp_WSAStartup'
- Git详解之五:分布式Git
- 返回类型和return语句
- android premission汇总
- Tkinter -- Toplevel
- bzoj 1494: [NOI2007]生成树计数
- Zookeeper学习(九):ZooKeeper 实现分布式锁
- Android_gridView应用实例
- 关于注重驱动与中间层的分离
- nodejs 使用socket.io与网页实时数据交互
- 计算机的启动
- 第七届蓝桥杯省赛总结
- uva 1169 Robotruck(简单区间dp)
- Spring中Quartz调度器的使用