题解:P12116 [NWRRC2024] Longest Common Substring
sunkuangzheng · · 题解
首先对题面做第一步转化:我们不关心最长公共子串的具体值,只关心它是否大于等于
注意到
那么进行 DP,设
然后最终的问题是,求
/**
* author: sunkuangzheng
* created: 19.11.2024 08:47:52
**/
#include<bits/stdc++.h>
#ifdef DEBUG_LOCAL
#include <mydebug/debug.h>
#endif
using ll = long long;
const int N = 5e5+5,mod = 998244353;
using namespace std;
int T,n,M,k,w,dp[105][8][2][1 << 16],m,len; string s;
void ad(int &x,int y){x = (x + y) % mod;}
vector<int> get(int n){
vector<int> f(len);
for(int o = 0;o < m;o ++) for(int j = 0;j < len;j ++) ad(f[j],dp[n][o][1][j]);
return f;
}int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin >> n >> M >> k >> s;
for(char c : s) w = w * 2 + c - '0';
m = (1 << k),len = (1 << m * 2);
for(int i = 0;i < m;i ++) dp[k][i][(i == w)][0] = 1;
for(int i = k;i < max(n,M);i ++) for(int o = 0;o < m;o ++) for(int r : {0,1})
for(int b = 0;b < len;b ++) for(int j : {0,1}){
int nw = o * 2 + j;
// if(dp[i][o][r][b]) debug(i,o,r,b),debug(i+1,nw%m,r|(nw%m==w),b|(1<<nw));
ad(dp[i+1][nw%m][r|(nw%m==w)][b|(1<<nw)],dp[i][o][r][b]);
}
auto f = get(n),g = get(M);
reverse(g.begin(),g.end());
for(int i = 0;i < m * 2;i ++) for(int j = len - 1;j >= (1 << i);j --)
if(j >> i & 1) ad(g[j - (1 << i)],g[j]);
int ans = 0;
for(int i = 0;i < len;i ++) ad(ans,1ll * f[i] * g[i] % mod);
cout << ans << "\n";
}