1. 程式人生 > 實用技巧 >字串題解

字串題解

題目大意

求有多少個長度為 \(n\) ,僅包含前 \(k\) 個小寫字母且包含至少一個長度不少於 \(2\) 的迴文串的字串作為子串。對於 \(k>26\) 的情況,你只需要把每個字母當成一個與其他字母均不同的字母,而無需關注它具體是什麼符號。答案需要對 \(998244353\)(一個質數)取模。

\(1\le n,k \le 10^9\)

example
in
3 3
out
21

分析

看到資料範圍,發現數學題沒跑。開始找規律

3 3
1  1  123
   2  12
   3  13
2  1  12
   2  123
   3  23
3  1  13
   2  23
   3  123
大概就是3*3*3-3*2

然後再推個幾下就會發現式子

\(ans=k^n-k*(k-1)*(k-2)^{(n-2)}\)

然後寫程式碼就是有手就行

#include <bits/stdc++.h>
#define MOD 998244353
#define int long long
using namespace std ;
int n , k ;
inline int Pow ( int a , int b ) {
    a %= MOD ; b %= MOD - 1 ;
    int res = 1 ;
    while ( b ) {
        if ( b & 1 ) res = res * a % MOD ;
        b >>= 1 ;
        a = a * a % MOD ;
    }
    return res ;
}
signed main () {
    cin >> n >> k ;
    if ( n == 1 ) cout << 0 << endl ; // 特判
    else if ( n == 2 ) cout << k % MOD << endl ;
    else {
        int ans = Pow ( k , n ) - ( ( k * ( k - 1 ) % MOD ) * Pow ( k - 2 , n - 2 ) % MOD ) % MOD ;
        cout << ( ans + MOD ) % MOD << endl ; // 避免出現負數
    }
}