题目大意

  有一个 \(n\) 个点的环,你要用 \(m\) 中颜色染这 \(n\) 个点。

  要求连续 \(m\) 个点的颜色不能是 $1 \sim m $ 的排列。

  两种环相同当且仅当这两个环可以在旋转之后变得一模一样。

  求方案数对 \({10}^9+7\) 取模的结果。

  \(n\leq {10}^9,m\leq 7\)

题解

  考虑 polya 定理,记 \(f(n)\) 为 \(n\) 个点的答案,\(g(n)\) 为 \(n\) 个点不考虑旋转的答案。那么就有

\[\begin{align}
f(n)&=\frac{1}{n}\sum_{i=1}^ng(\gcd(n,i))\\
&=\frac{1}{n}\sum_{i\mid n}\varphi(\frac{n}{i})g(i)
\end{align}
\]

  \(g(i)\) 可以 DP 计算。

  记 \(h_{i,j,k}\) 为长度为 \(i\) 的链,前 \(m\) 个点的状态(颜色)为 \(j\),最后 \(m\) 个点的状态为 \(k\) 的方案数。

  还可以记录前 \(m\) 个颜色的前多少个是互不相同的,还有最后 \(m\) 个点的颜色。就前 \(j\) 个的颜色是互不相同的,第 \(j+1\) 个点颜色和前面某个点颜色相同。

  显然 \(g(i)\) 有一个长度不超过 \(m^m\) 的递推式。

  暴力打出前面的项然后 BM 求出递推式即可。

  开 O2 只用了 48s 就打出来了。

  \(m=7\) 时递推式长度为 \(409\)。

  表在这:https://github.com/ywwywwyww/THUSC2017/tree/master/yww/farben

代码

  1. const int N=1010;
  2. const ll p=1000000007;
  3. ll fp(ll a,ll b)
  4. {
  5. ll s=1;
  6. for(;b;b>>=1,a=a*a%p)
  7. if(b&1)
  8. s=s*a%p;
  9. return s;
  10. }
  11. ll b[10][2010]=表;
  12. ll a[10][2010]=表;
  13. int c[N],d[N],t;
  14. ll pw[N][N];
  15. ll ans;
  16. int n,m;
  17. int s[N];
  18. int len;
  19. void add(int &a,ll b)
  20. {
  21. a=(a+b)%p;
  22. }
  23. void mul()
  24. {
  25. static int f[N];
  26. for(int i=0;i<=2*len;i++)
  27. f[i]=0;
  28. for(int i=0;i<=len;i++)
  29. if(s[i])
  30. for(int j=0;j<=len;j++)
  31. add(f[i+j],(ll)s[i]*s[j]);
  32. for(int i=0;i<=2*len;i++)
  33. s[i]=f[i];
  34. }
  35. void module()
  36. {
  37. for(int i=2*len;i>=len;i--)
  38. if(s[i])
  39. {
  40. for(int j=1;j<=len;j++)
  41. add(s[i-j],(ll)s[i]*b[m][j]);
  42. s[i]=0;
  43. }
  44. }
  45. void fp(int x)
  46. {
  47. if(!x)
  48. {
  49. for(int i=0;i<=2*len;i++)
  50. s[i]=0;
  51. s[0]=1;
  52. return;
  53. }
  54. fp(x>>1);
  55. mul();
  56. if(x&1)
  57. {
  58. for(int i=2*len;i>=1;i--)
  59. s[i]=s[i-1];
  60. s[0]=0;
  61. }
  62. module();
  63. }
  64. ll calc(int x)
  65. {
  66. if(x<=500)
  67. return a[m][x];
  68. fp(x-1);
  69. ll res=0;
  70. for(int i=1;i<=len;i++)
  71. res=(res+(ll)a[m][i]*s[i-1])%p;
  72. return res;
  73. }
  74. void dfs(int x,int y,ll phi)
  75. {
  76. if(x>t)
  77. {
  78. ans=(ans+calc(y)*phi)%p;
  79. return;
  80. }
  81. for(int i=0;i<d[x];i++)
  82. dfs(x+1,y*pw[x][i],phi*(c[x]-1)%p*pw[x][d[x]-i-1]%p);
  83. dfs(x+1,y*pw[x][d[x]],phi);
  84. }
  85. int main()
  86. {
  87. open("farben");
  88. scanf("%d%d",&n,&m);
  89. int _n=n;
  90. for(int i=2;i*i<=_n;i++)
  91. if(_n%i==0)
  92. {
  93. c[++t]=i;
  94. while(_n%i==0)
  95. {
  96. d[t]++;
  97. _n/=i;
  98. }
  99. }
  100. if(_n>1)
  101. {
  102. c[++t]=_n;
  103. d[t]=1;
  104. }
  105. for(int i=1;i<=t;i++)
  106. {
  107. pw[i][0]=1;
  108. for(int j=1;j<=d[i];j++)
  109. pw[i][j]=pw[i][j-1]*c[i]%p;
  110. }
  111. len=b[m][0];
  112. dfs(1,1,1);
  113. ans=ans*fp(n,p-2)%p;
  114. ans=(ans%p+p)%p;
  115. printf("%lld\n",ans);
  116. return 0;
  117. }

打表程序

  1. const ll p=1000000007;
  2. const int N=1010;
  3. const int n=1000;
  4. //const int m=5;
  5. int m;
  6. ll fp(ll a,ll b)
  7. {
  8. ll s=1;
  9. for(;b;b>>=1,a=a*a%p)
  10. if(b&1)
  11. s=s*a%p;
  12. return s;
  13. }
  14. const int MA=2100000;
  15. int e[MA];
  16. int ban[MA];
  17. vector<int> g[N];
  18. int pw[N];
  19. int ma;
  20. namespace gao1
  21. {
  22. int a[N],b[N],c[N];
  23. void dfs(int x)
  24. {
  25. if(x>m)
  26. {
  27. for(int i=1;i<=m;i++)
  28. b[i]=0;
  29. int tot=0;
  30. int s=0;
  31. int s2=0;
  32. int first=0;
  33. for(int i=1;i<=m;i++)
  34. {
  35. if(!b[a[i]])
  36. b[a[i]]=++tot;
  37. c[i]=b[a[i]];
  38. s+=c[i]*pw[i-1];
  39. s2+=a[i]*pw[i-1];
  40. if(c[i]<=c[i-1]&&!first)
  41. first=i-1;
  42. }
  43. if(tot==m)
  44. ban[s2]=1;
  45. else
  46. g[first].push_back(s);
  47. return;
  48. }
  49. for(int i=1;i<=m;i++)
  50. {
  51. a[x]=i;
  52. dfs(x+1);
  53. }
  54. }
  55. void gao()
  56. {
  57. dfs(1);
  58. }
  59. }
  60. namespace gao2
  61. {
  62. int a[N],b[N],c[N];
  63. void dfs(int x)
  64. {
  65. if(x>m)
  66. {
  67. for(int i=1;i<=m;i++)
  68. b[i]=0;
  69. for(int i=m;i>=1;i--)
  70. if(!a[i]||!b[a[i]])
  71. {
  72. c[i]=a[i];
  73. b[a[i]]=1;
  74. }
  75. else
  76. c[i]=0;
  77. int s=0,s1=0;
  78. for(int i=1;i<=m;i++)
  79. s+=c[i]*pw[i-1];
  80. for(int i=1;i<=m;i++)
  81. s1+=a[i]*pw[i-1];
  82. e[s1]=s;
  83. return;
  84. }
  85. for(int i=0;i<=m;i++)
  86. {
  87. a[x]=i;
  88. dfs(x+1);
  89. }
  90. }
  91. void gao()
  92. {
  93. dfs(1);
  94. }
  95. }
  96. int f[N];
  97. int h[2][MA];
  98. int d[MA];
  99. void add(int &a,int b)
  100. {
  101. a=(a+b)%p;
  102. }
  103. int append(int a,int b)
  104. {
  105. return a/(m+1)+b*pw[m-1];
  106. }
  107. namespace gao3
  108. {
  109. void gao(int x)
  110. {
  111. memset(d,0,sizeof d);
  112. for(int i=0;i<=ma;i++)
  113. {
  114. int flag=1;
  115. for(int y=i,j=1;j<=x;j++)
  116. {
  117. y=append(y,j);
  118. if(ban[y])
  119. {
  120. flag=0;
  121. break;
  122. }
  123. }
  124. d[i]=flag;
  125. }
  126. memset(h,0,sizeof h);
  127. int cur=0;
  128. for(auto v:g[x])
  129. h[cur][e[v]]++;
  130. for(int i=m;i<=n;i++)
  131. {
  132. fprintf(stderr,"%d %d %d\n",m,x,i);
  133. memset(h[cur^1],0,sizeof h[cur^1]);
  134. for(int j=0;j<=ma;j++)
  135. if(h[cur][j]&&!ban[j])
  136. {
  137. add(f[i],d[j]*h[cur][j]);
  138. for(int k=1;k<=m;k++)
  139. add(h[cur^1][e[append(j,k)]],h[cur][j]);
  140. }
  141. cur^=1;
  142. }
  143. }
  144. }
  145. int main(int argc,char **argv)
  146. {
  147. // freopen("farben2.txt","w",stdout);
  148. sscanf(argv[1],"%d",&m);
  149. ma=fp(m+1,m);
  150. pw[0]=1;
  151. for(int i=1;i<=m;i++)
  152. pw[i]=pw[i-1]*(m+1);
  153. gao1::gao();
  154. gao2::gao();
  155. for(int i=1;i<m;i++)
  156. f[i]=fp(m,i);
  157. for(int i=1;i<m;i++)
  158. gao3::gao(i);
  159. for(int i=1;i<=n;i++)
  160. printf("%d\n",f[i]);
  161. return 0;
  162. }

【THUSC2017】【LOJ2981】如果奇迹有颜色 DP BM 打表 线性递推的更多相关文章

  1. 【模板】BM + CH(线性递推式的求解,常系数齐次线性递推)

    这里所有的内容都将有关于一个线性递推: $f_{n} = \sum\limits_{i = 1}^{k} a_{i} * f_{n - i}$,其中$f_{0}, f_{1}, ... , f_{k ...

  2. HDU 5863 cjj's string game ( 16年多校10 G 题、矩阵快速幂优化线性递推DP )

    题目链接 题意 : 有种不同的字符,每种字符有无限个,要求用这k种字符构造两个长度为n的字符串a和b,使得a串和b串的最长公共部分长度恰为m,问方案数 分析 : 直觉是DP 不过当时看到 n 很大.但 ...

  3. HDU - 6172:Array Challenge (BM线性递推)

    题意:给出,三个函数,h,b,a,然后T次询问,每次给出n,求sqrt(an); 思路:不会推,但是感觉a应该是线性的,这个时候我们就可以用BM线性递推,自己求出前几项,然后放到模板里,就可以求了. ...

  4. BM求线性递推模板(杜教版)

    BM求线性递推模板(杜教版) BM求线性递推是最近了解到的一个黑科技 如果一个数列.其能够通过线性递推而来 例如使用矩阵快速幂优化的 DP 大概都可以丢进去 则使用 BM 即可得到任意 N 项的数列元 ...

  5. [NOI2017]泳池——概率DP+线性递推

    [NOI2017]泳池 实在没有思路啊~~~ luogu题解 1.差分,转化成至多k的概率减去至多k-1的概率.这样就不用记录“有没有出现k”这个信息了 2.n是1e9,感觉要递推然后利用数列的加速技 ...

  6. LG5487 【模板】线性递推+BM算法

    [模板]线性递推+BM算法 给出一个数列 \(P\) 从 \(0\) 开始的前 \(n\) 项,求序列 \(P\) 在\(\bmod~998244353\) 下的最短线性递推式,并在 \(\bmod~ ...

  7. 2018 焦作网络赛 L Poor God Water ( AC自动机构造矩阵、BM求线性递推、手动构造矩阵、矩阵快速幂 )

    题目链接 题意 : 实际上可以转化一下题意 要求求出用三个不同元素的字符集例如 { 'A' .'B' .'C' } 构造出长度为 n 且不包含 AAA.BBB CCC.ACB BCA.CAC CBC ...

  8. 牛客多校第九场 A The power of Fibonacci 杜教bm解线性递推

    题意:计算斐波那契数列前n项和的m次方模1e9 题解: $F[i] – F[i-1] – F[i-2] = 0$ $F[i]^2 – 2 F[i-1]^2 – 2 F[i-2]^2 + F[i-3] ...

  9. 【CF607B】Zuma——区间dp(记忆化搜索/递推)

    以下是从中文翻译成人话的题面: 给定一个长度小于等于500的序列,每个数字代表一个颜色,每次可以消掉一个回文串,问最多消几次可以消完? (7.16) 这个题从洛谷pend回来以后显示有103个测试点( ...

随机推荐

  1. Flutter map 妙用及 .. 使用

    前言 本篇文章对于熟悉 flutter 或者 dart 的小伙伴来说可能觉得比较简单,但是对于初学者或者没用过的小伙伴还是有些收获的. 背景 说到 map 妙用的发现,还要归功于 Tooltip 的研 ...

  2. java爬虫系列第二讲-爬取最新动作电影《海王》迅雷下载地址

    1. 目标 使用webmagic爬取动作电影列表信息 爬取电影<海王>详细信息[电影名称.电影迅雷下载地址列表] 2. 爬取最新动作片列表 获取电影列表页面数据来源地址 访问http:// ...

  3. java 深克隆(深拷贝)与浅克隆(拷贝)详解

    java深克隆和浅克隆 基本概念 浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对 ...

  4. 3Delight NSI: A Streamable Render API

    3Delight是应用于高端电影级别渲染的软件渲染器,迄今为止已经参与了无数的电影制作,具体可以参见链接. 如果你对3Delight的印象就依然是RenderMan的替代品,那就显然已经和时代发展脱节 ...

  5. .net 获取时间十二进制与二十四进制

    [说明] visual studio工具,.net项目,获取时间 [易错问题] ①二十四小时制(HH小时大写) System.DateTime.Now.ToString("yyyy-MM-d ...

  6. Python使用Plotly绘图工具,绘制面积图

    今天我们来讲一下如何使用Python使用Plotly绘图工具,绘制面积图 绘制面积图与绘制散点图和折线图的画法类似,使用plotly graph_objs 中的Scatter函数,不同之处在于面积图对 ...

  7. vue watch监听验证码时,axios延迟发送post请求。

    标题写的全面一些,方便其他人检索,我就是找了半天找不到资料,最后自己搞定了. 原理: 每次监听到输入值变化,就打一个时间戳,然后暂停2秒再去提交post验证. 但是每次提交前,判断一下之前打的时间戳和 ...

  8. 海思uboot启动流程详细分析(一)

    第一阶段 start.S 首先我们可以在u-boot.lds中看到ENTRY(_start),即指定了入口_start,_start也就是整个start.S的最开始: 1. reset 在arch\a ...

  9. 解决FileZilla访问手机ftp服务只能删除浏览文件不能下载文件的问题

    用了Linux系统之后,很多资源都不方便获取, 因为很多资料都是放在百某某盘上面. 无意中看到我手机有FTP服务,想到我电脑装有FileZilla,可以访问手机了 然后就连接上了. 但是浏览的时候发现 ...

  10. scrapy 命令行基本用法

    1.创建一个新项目: scrapy startproject myproject 2.在新项目中创建一个新的spider文件: scrapy genspider mydomain mydomain.c ...