【题解】CF1320D Reachable Strings

思路

对于 1 并不好考虑,可以针对 0 考虑。

发现每次移动会在一堆 1 之间移动把一个 0 移动 \(2\) 位,因此只需要记录所有 0 位置的奇偶性即可,具体实现可以用 Hash,对开头奇数/偶数分别开 Hash 表记录。

这里 Hash 实现有一个方法:(BKDRHash)

\[h_i = ph_{i-1} + s_i \]

这样可以非常容易地求出区间 Hash 值。(当然这里没写)

不要 unsigned long long 自然溢出啊,会被卡爆的 ......

Code

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
#define File(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
typedef long long ll;
typedef unsigned long long ull;
template<typename T> inline void gi(T &x){
	char ch; x = 0;
	int f = 1;
	while(isspace(ch = getchar()));
	if(ch == '-') ch = getchar(), f = -1;
	do x = x * 10 + ch - '0'; while(isdigit(ch = getchar()));
	x *= f;
}
template<class T> void upmax(T &x, T y){x = x>y ? x : y;}
template<class T> void upmin(T &x, T y){x = x<y ? x : y;}

const int N = 200005;
const ull p1 = 999983, p2 = 10007, mod1 = 104857601, mod2 = 167772161;
char s[N];
int cnt[N];

template<ull p, ull mod>
struct Hash{
	ull h[N], pw[N];
	int len;
	Hash(){pw[0] = 1; len = 0; h[0] = 0;}
	void hash(ull x){
		++len;
		pw[len] = pw[len - 1] * p % mod;
		h[len] = (h[len - 1] + x * pw[len]) % mod;
	}
	void space(){
		++len;
		h[len] = h[len - 1];
		pw[len] = pw[len - 1];
	}
	ull ask(int l, int r){
		return (h[r] - h[l - 1] + mod) % mod;
	}
};
Hash<p1, mod1> h01, h11;
Hash<p2, mod2> h02, h12;

int main(){
	// File("cf1320d");
	int n;
	gi(n);
	scanf("%s", s + 1);
	for(int i=1; i<=n; i++){
		if(s[i] == '1'){
			h01.space(); h11.space(); h02.space(); h12.space();
			cnt[i] = cnt[i-1];
		}
		else{
			h01.hash((i & 1) + 1); h02.hash((i & 1) + 1);
			h11.hash(((i & 1) ^ 1) + 1); h12.hash(((i & 1) ^ 1) + 1);
			cnt[i] = cnt[i-1] + 1;
		}
	}
	int q; gi(q);
	while(q--){
		int _l, _r, _len;
		gi(_l); gi(_r); gi(_len);
		int l1, r1, l2, r2;
		l1 = _l; r1 = _l  + _len - 1; l2 = _r; r2 = _r + _len - 1;
		if((cnt[r1] - cnt[l1 - 1]) != (cnt[r2] - cnt[l2 - 1])){
			puts("No");
			continue;
		}
		if((l1 ^ l2) & 1){
			ull h1 = h01.ask(l1, r1) * h11.pw[l2 - 1] % mod1;
			ull h2 = h11.ask(l2, r2) * h01.pw[l1 - 1] % mod1;
			if(h1 != h2){
				puts("No");
				continue;
			}
			h1 = h02.ask(l1, r1) * h12.pw[l2 - 1] % mod2;
			h2 = h12.ask(l2, r2) * h02.pw[l1 - 1] % mod2;
			if(h1 != h2){
				puts("No");
				continue;
			}
		}
		else{
			ull h1 = h01.ask(l1, r1) * h01.pw[l2 - 1] % mod1;
			ull h2 = h01.ask(l2, r2) * h01.pw[l1 - 1] % mod1;
			if(h1 != h2){
				puts("No");
				continue;
			}
			h1 = h02.ask(l1, r1) * h02.pw[l2 - 1] % mod2;
			h2 = h02.ask(l2, r2) * h02.pw[l1 - 1] % mod2;
			if(h1 != h2){
				puts("No");
				continue;
			}
		}
		puts("Yes");
	}
	return 0;
}
posted @ 2020-03-08 16:34  RiverHamster  阅读(163)  评论(0编辑  收藏  举报
\