传送门

考虑$c[i]>n/3$这个关键条件!最多有2个字母数量超过$n/3$!

没有奇数回文?长度大于3的回文串中间一定是长度为3的回文串,所以合法串一定没有长度=3的回文,也就是$a[i]\ne a[i-2]$恒成立

考虑没有数目限制的情况,除了前两个位置,其它位置都只能填25种字母,答案是$26*26*25^{n-2}$

再容斥掉数量限制

对于单个字母,我们去掉$j>c[i]$这些情况

再枚举两个字母,加回来$j>c[i_{1}]$且$k>c[i_{2}]$这些情况

由于最多有2个字母超过$n/3$,设为$a$和$b$

维护$f(i,j,k,s,t)$表示长度为i的串中,放了j个a字母,k个b字母,i-1放了s,i放了t,s和t只有a/b/其它字母三种情况

大力讨论转移,滚动数组压空间

再维护$g(i,j,s,t)$表示长度为i的串中,放了j个a字母,i-1放了s,i放了t

原理同上

最麻烦的就是预处理,我比较蠢直接讨论n的奇偶做的

  1 const int N1=405; const ll p=998244353;
2
3 ll qpow(ll x,ll y)
4 {
5 ll ans=1;
6 for(;y;x=x*x%p,y>>=1) if(y&1) ans=ans*x%p;
7 return ans;
8 }
9 int n,m;
10 ll f[2][N1][N1][3][3],g[2][N1][2][2],sf[N1][N1],sg[N1];
11 int a[N1];
12
13 int main()
14 {
15 scanf("%d",&n);
16 for(int i=1;i<=26;i++) scanf("%d",&a[i]);
17 int now=1, pst=0, st;
18 int j,k,s,t,u,v,x,y;
19 if(n&1){
20 f[pst][0][0][0][0]=24; f[pst][1][0][0][1]=1; f[pst][0][1][0][2]=1;
21 for(j=0;j<=1;j++) for(k=0;j+k<=1;k++)
22 {
23 for(s=0,t=0;t<=2;t++) for(u=0;u<=2;u++) for(v=0;v<=2;v++)
24 {
25 if(u) x=1; else x=24;
26 if(v){ if(v==t) y=0; else y=1; }
27 else{ if(t) y=24; else y=23; }
28 if(u==0)
29 {
30 if(v==0) (f[now][j][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
31 if(v==1) (f[now][j+1][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
32 if(v==2) (f[now][j][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
33 }
34 if(u==1)
35 {
36 if(v==0) (f[now][j+1][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
37 if(v==1) (f[now][j+2][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
38 if(v==2) (f[now][j+1][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
39 }
40 if(u==2)
41 {
42 if(v==0) (f[now][j][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
43 if(v==1) (f[now][j+1][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
44 if(v==2) (f[now][j][k+2][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
45 }
46 }
47 }
48 g[pst][0][0][0]=25; g[pst][1][0][1]=1;
49 for(j=0;j<=1;j++)
50 {
51 for(s=0,t=0;t<=1;t++) for(u=0;u<=1;u++) for(v=0;v<=1;v++)
52 {
53 if(u) x=1; else x=25;
54 if(v){ if(v==t) y=0; else y=1; }
55 else{ if(t) y=25; else y=24; }
56 if(u==0)
57 {
58 if(v==0) (g[now][j][u][v]+=g[pst][j][s][t]*x*y)%=p;
59 if(v==1) (g[now][j+1][u][v]+=g[pst][j][s][t]*x*y)%=p;
60 }
61 if(u==1)
62 {
63 if(v==0) (g[now][j+1][u][v]+=g[pst][j][s][t]*x*y)%=p;
64 if(v==1) (g[now][j+2][u][v]+=g[pst][j][s][t]*x*y)%=p;
65 }
66 }
67 }
68 st=3; swap(pst,now);
69 }else{
70 f[pst][0][0][0][0]=24*24; f[pst][1][0][1][0]=24; f[pst][0][1][2][0]=24;
71 f[pst][1][0][0][1]=24; f[pst][2][0][1][1]=1; f[pst][1][1][2][1]=1;
72 f[pst][0][1][0][2]=24; f[pst][1][1][1][2]=1; f[pst][0][2][2][2]=1;
73 g[pst][0][0][0]=25*25; g[pst][1][1][0]=25; g[pst][1][0][1]=25; g[pst][2][1][1]=1;
74 st=2;
75 }
76 for(int i=st+2;i<=n;i+=2)
77 {
78 memset(f[now],0,sizeof(f[now]));
79 for(j=0;j<=i;j++) for(k=0;j+k<=i;k++)
80 {
81 for(s=0;s<=2;s++) for(t=0;t<=2;t++) for(u=0;u<=2;u++) for(v=0;v<=2;v++)
82 {
83 if(u){ if(u==s) x=0; else x=1; }
84 else{ if(s) x=24; else x=23; }
85 if(v){ if(v==t) y=0; else y=1; }
86 else{ if(t) y=24; else y=23; }
87 if(u==0)
88 {
89 if(v==0) (f[now][j][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
90 if(v==1) (f[now][j+1][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
91 if(v==2) (f[now][j][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
92 }
93 if(u==1)
94 {
95 if(v==0) (f[now][j+1][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
96 if(v==1) (f[now][j+2][k][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
97 if(v==2) (f[now][j+1][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
98 }
99 if(u==2)
100 {
101 if(v==0) (f[now][j][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
102 if(v==1) (f[now][j+1][k+1][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
103 if(v==2) (f[now][j][k+2][u][v]+=f[pst][j][k][s][t]*x*y)%=p;
104 }
105 }
106 }
107 memset(g[now],0,sizeof(g[now]));
108 for(j=0;j<=i;j++)
109 {
110 for(s=0;s<=1;s++) for(t=0;t<=1;t++) for(u=0;u<=1;u++) for(v=0;v<=1;v++)
111 {
112 if(u){ if(u==s) x=0; else x=1; }
113 else{ if(s) x=25; else x=24; }
114 if(v){ if(v==t) y=0; else y=1; }
115 else{ if(t) y=25; else y=24; }
116 if(u==0)
117 {
118 if(v==0) (g[now][j][u][v]+=g[pst][j][s][t]*x*y)%=p;
119 if(v==1) (g[now][j+1][u][v]+=g[pst][j][s][t]*x*y)%=p;
120 }
121 if(u==1)
122 {
123 if(v==0) (g[now][j+1][u][v]+=g[pst][j][s][t]*x*y)%=p;
124 if(v==1) (g[now][j+2][u][v]+=g[pst][j][s][t]*x*y)%=p;
125 }
126 }
127 }
128 swap(now,pst);
129 }
130
131 for(j=1;j<=n;j++) for(k=1;k<=n;k++)
132 {
133 for(s=0;s<=2;s++) for(t=0;t<=2;t++)
134 (sf[j][k]+=f[pst][j][k][s][t])%=p;
135 }
136 for(int j=n;j>=1;j--) for(k=n;k>=1;k--)
137 sf[j][k]=(sf[j][k]+sf[j+1][k]+sf[j][k+1]-sf[j+1][k+1]+p)%p;
138 for(j=1;j<=n;j++) for(s=0;s<=1;s++) for(t=0;t<=1;t++)
139 (sg[j]+=g[pst][j][s][t])%=p;
140 for(j=n;j>=1;j--) (sg[j]+=sg[j+1])%=p;
141 m=n/3;
142 ll ans=qpow(25ll,n-2)*26*26%p;
143 for(s=1;s<=26;s++) ans=(ans-sg[a[s]+1]+p)%p;
144 for(s=1;s<=26;s++) for(t=s+1;t<=26;t++)
145 ans=(ans+sf[a[s]+1][a[t]+1])%p;
146 printf("%lld\n",ans);
147 return 0;
148 }

CF1487G String Counting (容斥计数)的更多相关文章

  1. 【BZOJ 4455】 [Zjoi2016]小星星 容斥计数

    dalao教导我们,看到计数想容斥……卡常策略:枚举顺序.除去无效状态.(树结构) #include <cstdio> #include <cstring> #include ...

  2. 数学(容斥计数):LNOI 2016 方

    Description 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一个有N行M列的方格图上,图上一共有(N+1)×(M+1) ...

  3. AGC 005D.~K Perm Counting(容斥 DP 二分图)

    题目链接 \(Description\) 给定\(n,k\),求 满足对于所有\(i\),\(|a_i-i|\neq k\)的排列的个数. \(2\leq n\leq 2000,\quad 1\leq ...

  4. Codeforces.997C.Sky Full of Stars(容斥 计数)

    题目链接 那场完整的Div2(Div1 ABC)在这儿.. \(Description\) 给定\(n(n\leq 10^6)\),用三种颜色染有\(n\times n\)个格子的矩形,求至少有一行或 ...

  5. 一本通 1783 矩阵填数 状压dp 容斥 计数

    LINK:矩阵填数 刚看到题目的时候感觉是无从下手的. 可以看到有n<=2的点 两个矩形. 如果只有一个矩形 矩形外的方案数容易计算考虑 矩形内的 必须要存在x这个最大值 且所有值<=x. ...

  6. 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 359 Description Al ...

  7. Co-prime HDU - 4135_容斥计数

    Code: #include<cstdio> #include<cstring> #include<cmath> #include<iostream> ...

  8. How many integers can you find HDU - 1796_容斥计数

    Code: #include<cstdio> using namespace std; typedef long long ll; const int R=13; ll a[R]; ll ...

  9. Comet OJ - Contest #2 (D 错综的光影所迷惑的思念是) 容斥计数

    题意:给定一颗 $n$ 个节点的树,定义 $dis(x,y)$ 为树上点 $x$ 到 $y$ 的路径经过的边数. 定义一个点集 $S$ 的 $f(S)$ 为 $f(S)=max\left \{dis( ...

随机推荐

  1. Redis持久化、主从与哨兵架构详解

    目录 Redis持久化 RDB快照(snapshot) AOF(append-only file) AOF重写 Redis 4.0 混合持久化 Redis数据备份策略: Redis主从架构 Redis ...

  2. html-拖拽释放(Drag and drop) API

    前言 本文总结一下html5 新增的元素拖拽功能的使用. 正文 1.H5之前的拖拽功能实现方法 JS 拖 拖 拽 功 能 的 实 现首先是三个事件,分别是 mousedown,mousemove,mo ...

  3. 关于WebStorm 破解

    建议资金宽裕,支持正版 2017.2.27更新 选择"license server" 输入:http://idea.imsxm.com/ 2016.2.2 版本的破解方式: 安装以 ...

  4. [Golang]一些书城项目中出现错误的原因和解决办法(二)

    跟着B站尚硅谷的GoWeb教程写书城项目,整理一下自己写的时候出现的错误和解决办法. 错误三:数据库的 cart_items 表中 total_count 始终为 0. 原因:更新购物车信息的 Upd ...

  5. CSRF POST型

    实验目的 掌握POST型CSRF基础知识 实验原理 管理员点击恶意链接,密码被修改 实验内容 POST型CSRF漏洞 实验环境描述 带有CSRF漏洞的注册登录系统 实验步骤 登录密码 用户名为 roo ...

  6. [c语言]左移和右移

    左移和右移都是位运算的概念.我们知道计算机是基于二进制保存数据的,因此左移和右移的概念十分重要.本文约定是32位的机器. [左移] 丢弃最高位,0补最低位 左移是把一个数按照二进制每位向左移动若干位, ...

  7. C#编程学习(一)

    1.1 开始在Visual Studio 2013环境中编程 控制台应用程序是在命令提示符窗口而非图形用户界面(GUI)中运行的应用程序. 集成开发环境(Integrated Development  ...

  8. Oracle之单行函数(字符串函数/数字函数/转换函数/日期函数/通用函数)

    虚拟表DUAL介绍: dual是一张虚拟表,只有一行一列,用来构成select的语法规则. Oracle的查询中,必须使用"select 列- from 表"的完整语法,当查询单行 ...

  9. idea教程--快速插入依赖

    1.打开pom.xml文件,按下快捷键Alt+insert,弹出Generate框,选择Dependency. 2.搜索所需jar的关键字. 3.点击add.添加jar包成功.如果第二步没有所要jar ...

  10. JZ-035-数组中的逆序对

    数组中的逆序对 题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即 ...