题解:CF2174C1 Beautiful Patterns (Easy Version)
Little_Crocodile · · 题解
题目大意
给你三个整数
分析
首先,设
此时发现这个式子可以分为两个步骤来计算。
计算 E(\sum f^2(l,r))
首先,这个平方让人很难受,但是因为
首先设我们枚举到的区间长度为
计算 2E(\sum_{(l,r)\not=(l',r')}f(l,r)\times f(l',r'))
这其实就是求两个子串同时为回文串时的期望,我们设这两个子串的长度分别为
- 两个子串有共同的中点。此时很明显期望取决于长的那个子串,即
\frac{m^{\lceil \frac{\max(len_1,len_2)}{2}\rceil}}{m^{\max(len_1,len_2)}} 。 - 两个子串没有共同的中点,且不相交。这个时候明显两个字符串互不影响,答案为
\frac{m^{\lceil \frac{len_1}{2}\rceil}}{m^{len_1}}\times\frac{m^{\lceil \frac{len_2}{2}\rceil}}{m^{len_2}}=\frac{m^{\lceil \frac{len_1}{2}\rceil+\lceil \frac{len_2}{2}\rceil}}{m^{len_1+len_2}} 。 - 两个子串没有共同的中点,且相交。此时设相交长度为
L ,此时还要分类: -
然后我们惊奇的发现,第
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e3 + 10;
int T, n, m, p, now[N];
int qpow(int x, int y, const int MOD) {
int ans = 1;
while(y) {
if(y & 1) {
ans = ans * x % MOD;
}
x = x * x % MOD;
y >>= 1;
}
return ans;
}
void solve() {
cin >> n >> m >> p;
int ans = 0;
for(int i = 1; i <= n; i++) {
now[i] = qpow(m, (i + 1) / 2, p) * qpow(qpow(m, i, p), p - 2, p) % p;
ans = (ans + now[i] * (n - i + 1) % p) % p;
}
for(int l1 = 1; l1 <= n; l1++) {
ans = (ans + now[l1] * (n - l1 + 1) % p * ((l1 - 1) / 2) % p * 2 % p) % p;
for(int l2 = 1; l2 < l1; l2++) {
ans = (ans + now[l1] * now[l2] % p * (n - l1 + 1) % p * (n - l2 + ((l2 & 1) ^ (l1 & 1))) % p * 2 % p) % p;
}
ans = (ans + (n - l1 + 1) * (n - l1) % p * now[l1] % p * now[l1] % p) % p;
}
cout << ans << "\n";
}
signed main() {
cin >> T;
while(T--) {
solve();
}
return 0;
}
完结撒花★,°:.☆( ̄▽ ̄)/$:.°★ 。