正题

题目链接:https://www.luogu.com.cn/problem/CF848E


题目大意

\(2n\)个花排成一个圆环,\(n\)种颜色每种两个,要求两个相同颜色之间最小距离为\(1,2\)或\(n\)。

对于一种染色方案的权值为:删除掉距离为\(n\)的颜色后,剩下的连续段长度的乘积。

求所有方案的染色之和对\(998244353\)取模。

\(1\leq n\leq 50000\)


解题思路

环好像很麻烦,先考虑线段上的,现在有两个长度为\(n\)的数列,然后距离为\(n\)的点之间对应。染色可以看为连接两个点。

然后设\(g_i\)表示不使用跨越数列的连线,涂\(i\)个的方案数,那么有\(g_i=g_{i-2}+g_{i-4}\)(相邻的连接/两个都是隔着对方连)。

然后考虑有跨越数列的线的方案,且没有其他连线跨过这条线,\(f0_i\)表示第\(i\)个是满足条件的线的权值和。\(f1_i\)则表示刚好有一对距离为\(2\)的点对跨越这个线的权值和。

那么有转移方程

\[f0_i=g_ii^2+\sum_{j=0}^{i-1}g_jj^2f0_{i-j-1}+\sum_{j=0}^{i-3}g_j(j+1)^2f1_{i-j-3}
\]

(第一个是全程没有其他横跨边,第二个是上一条横跨边两边没有同色,第三个是上一条横跨边两边有同色)

同理可以得到\(f1\)的方程

\[f1_i=g_i(i+1)^2+\sum_{j=0}^{i-1}g_j(j+1)^2f0_{i-j-1}+\sum_{j=0}^{i-3}g_j(j+2)^2f1_{i-j-3}
\]

得到\(f0\)和\(f1\)之后,看一下\(f0,f1\)都是最左边没有距离为\(2\)的边越过的,但是我们转换到环上的时候需要考虑这种情况,所以我们设\(f2_i\)表示左右两边的横跨边都有同色的,中间距离为\(i\)的权值和。

方程是

\[f2_i=g_i(i+2)^2+\sum_{j=0}^{i-1}g_j(j+1)^2f0_{i-j-1}+\sum_{j=0}^{j-3}g_j(j+2)^2f1_{i-j-3}
\]

然后考虑转换到行上。

如果只有一个点对距离是\(n\),那么贡献是\((n-1)\),有\(n\)种旋转方法,如果这个点对两边没有同色点,那么方案数是\(g_{n-1}\),否则是\(g_{n-3}\),所以这种情况的方案是\((n-1)^2n(g_{n-1}+g_{n-3})\)

然后剩下的我们可以先固定\(1\sim n+1\),然后枚举第二个距离为\(n\)的点对。设为\(i\),那贡献就是$$i(i-1)^2(g_{i-1}f0_{n-i-1}+2g_{i-2}f1_{n-i-2}+g_{i-3}f2_{n-i-3})$$

然后前面求\(f0,f1,f2\)都可以用分治\(NTT\)搞。

时间复杂度\(O(n\log^2 n)\)

如果用生成函数再推推可以分别得到\(O(n)\)和\(O(n\log n)\)的方法。

还有可以用生成函数发现这是一个\(16\)项的线性递推式,打出前面的表再用高斯消元得到系数,可以把时间优化到\(log\)级别

路还很长啊


code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define ll long long
  5. using namespace std;
  6. const ll N=2e5+10,P=998244353;
  7. ll n,m,r[N],g[N],h[3][N],f[3][N];
  8. ll t[3][N],T[2][N],z[4][N];
  9. ll power(ll x,ll b){
  10. ll ans=1;
  11. while(b){
  12. if(b&1)ans=ans*x%P;
  13. x=x*x%P;b>>=1;
  14. }
  15. return ans;
  16. }
  17. void Glen(ll n){
  18. m=1;while(m<=n)m<<=1;
  19. for(ll i=0;i<m;i++)
  20. r[i]=(r[i>>1]>>1)|((i&1)?(m>>1):0);
  21. return;
  22. }
  23. void NTT(ll *f,ll op){
  24. for(ll i=0;i<m;i++)
  25. if(i<r[i])swap(f[i],f[r[i]]);
  26. for(ll p=2;p<=m;p<<=1){
  27. ll len=(p>>1),tmp=power(3,(P-1)/p);
  28. if(op==-1)tmp=power(tmp,P-2);
  29. for(ll k=0;k<m;k+=p){
  30. ll buf=1;
  31. for(ll i=k;i<k+len;i++){
  32. ll tt=buf*f[i+len]%P;
  33. f[i+len]=(f[i]-tt+P)%P;
  34. f[i]=(f[i]+tt)%P;
  35. buf=buf*tmp%P;
  36. }
  37. }
  38. }
  39. if(op==-1){
  40. ll inv=power(m,P-2);
  41. for(ll i=0;i<m;i++)
  42. f[i]=f[i]*inv%P;
  43. }
  44. return;
  45. }
  46. void CDQ(ll l,ll r){
  47. if(l==r){
  48. (f[0][l]+=h[0][l])%=P;
  49. (f[1][l]+=h[1][l])%=P;
  50. return;
  51. }
  52. ll mid=(l+r)>>1;CDQ(l,mid);
  53. Glen((r-l+1)*2);
  54. for(ll i=0;i<m;i++)
  55. t[0][i]=t[1][i]=t[2][i]=T[0][i]=T[1][i]=0;
  56. for(ll i=0;i<=r-l+1;i++)
  57. t[0][i]=h[0][i],t[1][i]=h[1][i],t[2][i]=h[2][i];
  58. for(ll i=0;i<=mid-l;i++)
  59. T[0][i]=f[0][i+l],T[1][i]=f[1][i+l];
  60. NTT(t[0],1);NTT(t[1],1);NTT(t[2],1);
  61. NTT(T[0],1);NTT(T[1],1);
  62. for(ll i=0;i<m;i++){
  63. z[0][i]=t[0][i]*T[0][i]%P,z[1][i]=t[1][i]*T[1][i]%P;
  64. z[2][i]=t[1][i]*T[0][i]%P,z[3][i]=t[2][i]*T[1][i]%P;
  65. }
  66. NTT(z[0],-1);NTT(z[1],-1);NTT(z[2],-1);NTT(z[3],-1);
  67. for(ll i=0;i<=r-l+1;i++){
  68. if(l+i+1>mid&&l+i+1<=r){
  69. f[0][l+i+1]=(f[0][l+i+1]+z[0][i])%P;
  70. f[1][l+i+1]=(f[1][l+i+1]+z[2][i])%P;
  71. }
  72. if(l+i+3>mid&&l+i+3<=r){
  73. f[0][l+i+3]=(f[0][l+i+3]+z[1][i])%P;
  74. f[1][l+i+3]=(f[1][l+i+3]+z[3][i])%P;
  75. }
  76. }
  77. CDQ(mid+1,r);return;
  78. }
  79. void solve(ll l,ll r){
  80. if(l==r){(f[2][l]+=h[2][l])%=P;return;}
  81. ll mid=(l+r)>>1;solve(l,mid);
  82. Glen((r-l+1)*2);
  83. for(ll i=0;i<m;i++)
  84. t[1][i]=t[2][i]=T[0][i]=T[1][i]=0;
  85. for(ll i=0;i<=r-l+1;i++)
  86. t[1][i]=h[1][i],t[2][i]=h[2][i];
  87. for(ll i=0;i<=mid-l;i++)
  88. T[0][i]=f[1][l+i],T[1][i]=f[2][l+i];
  89. NTT(t[1],1);NTT(t[2],1);NTT(T[0],1);NTT(T[1],1);
  90. for(ll i=0;i<m;i++){
  91. z[0][i]=t[1][i]*T[0][i]%P;
  92. z[1][i]=t[2][i]*T[1][i]%P;
  93. }
  94. NTT(z[0],-1);NTT(z[1],-1);
  95. for(ll i=0;i<r-l+1;i++){
  96. if(l+i+1>mid&&l+i+1<=r)
  97. (f[2][l+i+1]+=z[0][i])%=P;
  98. if(l+i+3>mid&&l+i+3<=r)
  99. (f[2][l+i+3]+=z[1][i])%=P;
  100. }
  101. solve(mid+1,r);
  102. return;
  103. }
  104. signed main()
  105. {
  106. freopen("a.in","r",stdin);
  107. freopen("a.out","w",stdout);
  108. scanf("%lld",&n);g[0]=g[2]=1;
  109. for(ll i=4;i<=n;i++)
  110. g[i]=(g[i-4]+g[i-2])%P;
  111. for(ll i=0;i<=n;i++){
  112. h[0][i]=g[i]*i%P*i%P;
  113. h[1][i]=g[i]*(i+1)%P*(i+1)%P;
  114. h[2][i]=g[i]*(i+2)%P*(i+2)%P;
  115. }
  116. CDQ(0,n);
  117. solve(0,n);
  118. ll ans=(g[n-1]+g[n-3])*(n-1)%P*(n-1)%P*n%P;
  119. for(ll i=2;i<n-1;i++){
  120. ll tmp=g[i-1]*f[0][n-i-1]%P;
  121. tmp=(tmp+2*g[i-2]*f[1][n-i-2]%P)%P;
  122. tmp=(tmp+g[i-3]*f[2][n-i-3]%P)%P;
  123. tmp=tmp*i%P*(i-1)%P*(i-1)%P;
  124. ans=(ans+tmp)%P;
  125. }
  126. printf("%lld\n",ans);
  127. return 0;
  128. }

CF848E-Days of Floral Colours【dp,分治NTT】的更多相关文章

  1. CF848E Days of Floral Colours——DP+多项式求逆/分治NTT

    官方题解:http://codeforces.com/blog/entry/54233 就是由简入繁 1.序列处理,只考虑一个半圆 2.环形处理(其实这个就是多了旋转同构) 然后基于分割线邻居的跨越与 ...

  2. Codeforces 848E - Days of Floral Colours(分治 FFT)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙 D1E,一道货真价实的 *3400 %%%%%%%%%%%% 首先注意到一点,由于该图为中心对称图形,\(1\sim n\) 的染色 ...

  3. HDU 5279 YJC plays Minecraft (分治NTT优化DP)

    题目传送门 题目大意:有$n$个小岛,每个小岛上有$a_{i}$个城市,同一个小岛上的城市互相连接形成一个完全图,第$i$个小岛的第$a_{i}$个城市和第$i+1$个小岛的第$1$个城市连接,特别地 ...

  4. HDU 5322 Hope (分治NTT优化DP)

    题面传送门 题目大意: 假设现在有一个排列,每个数和在它右面第一个比它大的数连一条无向边,会形成很多联通块. 定义一个联通块的权值为:联通块内元素数量的平方. 定义一个排列的权值为:每个联通块的权值之 ...

  5. ZOJ 3874 Permutation Graph (分治NTT优化DP)

    题面:vjudge传送门 ZOJ传送门 题目大意:给你一个排列,如果两个数构成了逆序对,就在他们之间连一条无向边,这样很多数会构成一个联通块.现在给出联通块内点的编号,求所有可能的排列数 推来推去容易 ...

  6. 【BZOJ-3456】城市规划 CDQ分治 + NTT

    题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=3456 Solution 这个问题可以考虑dp,利用补集思想 N个点的简单图总数量为$2^{ ...

  7. CF960G Bandit Blues 分治+NTT(第一类斯特林数)

    $ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...

  8. CF 848E(动态规划+分治NTT)

    传送门: http://codeforces.com/problemset/problem/848/E 题解: 假设0-n一定有一条边,我们得到了一个方案,那么显然是可以旋转得到其他方案的. 记最大的 ...

  9. Codeforces 1553I - Stairs(分治 NTT+容斥)

    Codeforces 题面传送门 & 洛谷题面传送门 u1s1 感觉这道题放到 D1+D2 里作为 5250 分的 I 有点偏简单了吧 首先一件非常显然的事情是,如果我们已知了排列对应的阶梯序 ...

随机推荐

  1. wpf 实现印章,公章效果

    能写一些特定外观的控件,是一个做界面开发的程序员的基础技能.基本上,不管你是做web,QT,MFC,Winform,WPF等等,如果自己看到一个比较好看的有趣的效果,能大致推断出它的实现方式并照猫画虎 ...

  2. Qt简单的文件创建和读写

    1 QFile fp; //要包含必要的头文件,这里省略 2 QDir(dir); 3 QString path("./"),filename("test.txt&quo ...

  3. C# Monitor.Wait() 源码追踪 (转载)

    source: 释放对象上的锁并阻止当前线程,直到它重新获取该锁. 如果已用指定的超时时间间隔,则线程进入就绪队列. 可以在等待之前退出同步上下文的同步域,随后重新获取该域. [SecuritySaf ...

  4. 【转】TCP的三次握手与四次挥手理解及面试题

    转自:https://blog.csdn.net/qq_38950316/article/details/81087809 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据 ...

  5. 解决servlet中get方式中中文乱码问题前驱(一):装饰者模式再理解

    package day02; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; ...

  6. 项目中经常用到的sass语法汇总

    1.定义变量 使用:$(符号定义变量) 注意:使用时要带有'$'符号,定义变量的方式与PHP相同 $变量:数值; $color_r : red; div{ color:$color_r; } 2.if ...

  7. vue 优化hash持久化缓存

    公司用的是vue最近在学习react的打包时发现react会额外生成一个runtimeChunk,不知道具体原因所以查资料学习了下, 这里是runtime的功能,文章地址:https://sebast ...

  8. 高性能利器:CDN我建议你好好学一下!

    硬核干货分享,欢迎关注[Java补习课]成长的路上,我们一起前行 ! <高可用系列文章> 已收录在专栏,欢迎关注! CDN 概述 CDN 全称 Content Delivery Netwo ...

  9. mybatis第一个程序随笔

    今天继续学习了解如何写一个mybatis程序 创建了Dao层 1.1 创建一个UserDao接口 1.2 创建UserMapper.xml文件 在mybaits中文手册查找配置信息 <?xml ...

  10. Kubernetes-kubectl介绍

    前言 本篇是Kubernetes第三篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战.本篇重要介绍kubectl的使用. Kubernetes系列文章: Kubernetes介绍 Kuber ...