题解:P11959 「ZHQOI R1」诗歌
yingkeqian9217 · · 题解
赛时做法,不知道官方题解为什么这么复杂,赶紧来发个题解。
显然一个串是动听的充要条件是任意两个相同字符坐标差超过
注意到开头已经给了
对每种字符进行考虑,如果这个字符在开头
显然可以不考虑已确定的末位字符
可以直接 dp,
时间复杂度
#include<bits/stdc++.h>
#define maxn 2010
#define int long long
using namespace std;
const int Mod=998244353,N=1e7;
inline int reduce(int x){if(x>=Mod) return x-=Mod;return x;}
int q,k,m,f[N+100],bas[maxn];
inline int query(int x){
if(x<0) return 0;
return f[x];
}
inline void solve(){
int res=1;
scanf("%lld%lld%lld",&q,&k,&m);
m+=2;
bas[0]=1;
for(int i=1;i<=m;i++) bas[i]=bas[i-1]*(k-m)%Mod;
f[0]=1;
for(int i=1;i<=N;i++){
if(i>m) f[i]=(f[i-1]*(k-m-1)+f[i-m-1]*bas[m])%Mod;
else f[i]=f[i-1]*(k-m-1)%Mod;
}
while(q--){
int n;
scanf("%lld",&n);
unordered_map<int,int>mp;
for(int i=1,x;i<=m;i++) scanf("%lld",&x),mp[x]=i;
int len,ans=0;
scanf("%lld",&len);
while(len--){
int x;
scanf("%lld",&x);
if(!mp.count(x)) ans=reduce(ans+query(n-m-1));
else ans=(ans+query(n-mp[x]-m-1)*bas[mp[x]])%Mod;
}
printf("%lld\n",ans);
}
}
signed main(){
signed C,T=1;
scanf("%d",&C);
while(T--) solve();
return 0;
}