CF1849C Binary String Copying 题解
考虑到由于字符集只为 或 ,可以字符串哈希。容易发现 不会对哈希结果造成影响。对于一段排序,肯定是前面一段 ,后面是一段 。前面的 对哈希值的贡献都为 ,只需要管后面的 的数量。
所以我们可以预处理 表示有 个 的哈希值。使用前缀和维护区间 个数即可。
用哈希判重。
由于是 CF 的题,考虑双哈希。
#pragma GCC optimize("-Ofast,-inline")
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <cstdlib>
#include <string>
using namespace std;
#define ll long long
const int N = 2e5 + 5, INF = 2e9, MOD = 1e9 + 7;
inline int read()
{
int op = 1, x = 0;
char ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
while (ch == '-')
{
op = -op;
ch = getchar();
}
while (ch >= '0' and ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * op;
}
inline void write(int x)
{
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int n, m, t;
string s;
using ull = unsigned long long;
const long long MOD2 = 1e9 + 7;
ull hashing1[N];
long long hashing2[N];
int cnt[N];
ull hash1(ull x, ull p)
{
return x * 27 + p;
}
ll hash2(ll x, ll p)
{
return (x * 27LL % MOD2 + p) % MOD2;
}
ull hashing11[N];
ll hashing22[N];
ull powe1[N];
ll powe2[N];
ull gethash(string t)
{
ull res = 0;
for (char i : t)
{
res = res * 27 + (i - '0');
}
return res;
}
int main()
{
ios::sync_with_stdio(0), cin.tie(nullptr), cout.tie(nullptr);
// freopen("*.in", "r", stdin);
// freopen("*.out", "w", stdout);
powe1[0] = powe2[0] = 1;
for (int i = 1; i < N; i++)
{
hashing11[i] = hash1(hashing11[i - 1], 1);
hashing22[i] = hash2(hashing22[i - 1], 1);
powe1[i] = powe1[i - 1] * 27;
powe2[i] = powe2[i - 1] * 27LL % MOD2;
}
cin >> t;
while (t--)
{
cin >> n >> m;
cin >> s;
string p = " ";
s = p + s;
for (int i = 1; i <= n; i++)
{
hashing1[i] = hash1(hashing1[i - 1], s[i] - '0');
hashing2[i] = hash2(hashing2[i - 1], s[i] - '0');
cnt[i] = cnt[i - 1] + (s[i] == '1');
}
set<pair<ull, ll> > st;
while (m--)
{
int l, r;
cin >> l >> r;
ull nh1 = hashing1[l - 1] * powe1[n - l + 1] + hashing11[(cnt[r] - cnt[l - 1])] * powe1[n - r] + (r == n ? 0 : hashing1[n] - hashing1[r] * powe1[n - r]);
ll nh2 = (hashing2[l - 1] * powe2[n - l + 1] % MOD2 + hashing22[(cnt[r] - cnt[l - 1])] * powe2[n - r] % MOD2 + (r == n ? 0 : hashing2[n] - (hashing2[r] * powe2[n - r] % MOD2) + MOD2) % MOD2) % MOD2;
//cout << nh1 << " " << nh2 << "\n";
st.insert(make_pair(nh1, nh2));
}
cout << st.size() << "\n";
}
return 0;
}