CF1849C Binary String Copying 题解

考虑到由于字符集只为 0011,可以字符串哈希。容易发现 00 不会对哈希结果造成影响。对于一段排序,肯定是前面一段 00,后面是一段 11。前面的 00 对哈希值的贡献都为 00,只需要管后面的 11 的数量。

所以我们可以预处理 fif_i 表示有 ii11 的哈希值。使用前缀和维护区间 11 个数即可。

用哈希判重。

由于是 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;
}
posted @   HappyBobb  阅读(13)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示