atcorder 295 D
題目鏈接:https://atcoder.jp/contests/abc295/tasks/abc295_d
題意:
給定一個字符串,字符串中僅包含數字字符,問其中有多少個子串,滿足條件:通過重新排列以后,得到的新的字符串是某個字符串重復兩次的結果。
Sample:
20230322
4
樣例說明:滿足題意的子串有[1, 6], [1, 8], [2, 7], [7, 8]。
input:
一個字符串。
output
一個整數,表示符合題意的子串的總數。
Solution:
因為子串要能夠在通過重新排列后形成某個字符串重復兩次的結果,所以很明顯地,每個符合題意的子串,它里面每種字符的數目都是偶數。而且只要它里面每種字符的數目是偶數次,那么一定符合題意,反之,一定不合題意。
定義Ri:在字符串的前i個字符中,每個字符出現的次數mod2。
對于樣例有:
i = 0 0000000000
i = 1 0010000000
i = 2 1010000000
i = 3 1000000000
i = 4 1001000000
i = 5 0001000000
i = 6 0000000000
i = 7 0010000000
i = 8 0000000000
那么滿足題意的子串[i, j],有且僅有Rj - 1 = Ri這一種情況, 因為只有這種情況子串中每個字符出現的次數是偶數次。
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
string s; cin >> s;
vector<int> cnt(10, 0);
map<vector<int>, LL> mp;
mp[cnt] ++;
for(int i = 0; i < s.size(); i ++) {
cnt[s[i] - '0'] ++;
cnt[s[i] - '0'] %= 2;
mp[cnt] ++;
}
LL ans = 0;
for(auto[x, y] : mp) {
ans += (LL)(y) * (y - 1) / 2;
}
cout << ans;
}

浙公網安備 33010602011771號