Codeforces 1065E. Side Transmutations (Burnside's Lemma) 日付: 11月 18, 2018 リンクを取得 Facebook × Pinterest メール 他のアプリ [Problem - 1065E - Codeforces](https://codeforces.com/problemset/problem/1065/E) ## Problem Consider a set of strings {S∣Si∈A,∣S∣=n}\{S |S_i \in A,|S|=n\}{S∣Si∈A,∣S∣=n}. Given an array bbb of mmm integers, define an operation as: 1. Choose some value in bbb, called kkk 2. Get the subsequence of SSS that is the prefix kkk and suffix kkk, and reverse it The operations can be applied arbitrary times. If string TTT can be transformed from SSS by such operations, they are equivalent. The task is to calculate the number of equivalence classes of the set. **Constraints**: 2≤n≤109,1≤m≤min(n2,2⋅105),1≤∣A∣≤109,1≤b1<b2<⋯<bm≤n22\le n \le 10^9,1\le m \le min(\frac{n}{2}, 2\cdot 10^5), 1 \le |A| \le 10^9, 1 \le b_1 < b_2 < \cdots < b_m \le \frac{n}{2}2≤n≤109,1≤m≤min(2n,2⋅105),1≤∣A∣≤109,1≤b1<b2<⋯<bm≤2n ## Solution The problem can be solved with **Burnside's lemma**.∣Classes∣=1∣G∣∑π∈GI(π)|Classes|=\frac{1}{|G|}\sum_{\pi \in G}I(\pi)∣Classes∣=∣G∣1π∈G∑I(π) Firstly, we can observe that for any bib_ibi, if it is choosed twice, the string will not change. Thus any **invariant permutation** can be represented by a bitmask, ∣G∣=2m|G|=2^m∣G∣=2m. If we choose some elements in bbb, the string SSS is divided into several segments, alternating in two cases, remain origin or is the reverse of its symetric segment. We want to calculate the number of **invariant points**, that is, I(π)I(\pi)I(π). For the first case any character can be chosen. For the second case, we can choose for one segment arbitrarily, but its symetric segment is fixed. I(π)=∣A∣n−sI(\pi)=|A|^{n-s}I(π)=∣A∣n−s, where sss is half of the total length of segments in the second case. We iterator on the elements of bbb and maintain two values: x=∑∣A∣n−spx=\sum |A|^{n-s_p}x=∑∣A∣n−sp, y=∑∣A∣n+spy=\sum|A|^{n+s_p}y=∑∣A∣n+sp. For each element of bbb, there are two cases, whether or not this element is chosen. If this element is chosen, then, segments before the current value is flipped over. ## Code ```c++ #include <bits/stdc++.h> using namespace std; using LL = long long; using PII = pair<int, int>; #define FI(i,a,b) for(int i=(a);i<=(b);++i) #define FD(i,b,a) for(int i=(b);i>=(a);--i) #define DEBUG(x) cerr << #x << ": " << (x) << endl; constexpr LL inv(LL x, LL m) { return x > m ? inv(x % m, m) : x > 1 ? inv(m % x, m) * (m - m / x) % m : x; } constexpr LL mpow(LL a, LL k, LL m) { LL r(1); for (a %= m; k; k >>= 1, a = a * a % m) if (k & 1)r = r * a % m; return r; } int main() { int n, m, k; scanf("%d%d%d", &n, &m, &k); vector<int> B(m + 1); FI(i, 1, m) scanf("%d", &B[i]); const int Mod = 998244353; LL a = mpow(k, n, Mod), b = mpow(k, n, Mod); FI(i, 1, m) { LL na = b * inv(mpow(k, B[i], Mod), Mod) % Mod; LL nb = a * mpow(k, B[i], Mod) % Mod; a = (a + na) % Mod; b = (b + nb) % Mod; } LL ans = a * inv(mpow(2, m, Mod), Mod) % Mod; cout << ans << endl; } ``` コメント
コメント
コメントを投稿