P8271 [USACO22OPEN] COW Operations S (思維)

Fire_Raku發表於2024-07-06

P8271 [USACO22OPEN] COW Operations S

思維題

遇到不明白的操作,嘗試在紙上模擬操作過程,找到性質。

第一種操作目前沒有什麼特別的,有一個它不會改變字元的奇偶性。重點是第二個。我們容易發現 CO->W->OC 這樣的過程,它實現了相鄰位置的互換,這個性質正是氣泡排序的過程,所以字元的排列不再重要。

有了這個性質,操作一中的相鄰也可以去掉。

現在可以考慮什麼時候合法了。容易發現只有兩種情況:

  1. C 為奇數,OW 都為偶數。
  2. C 為偶數,OW 都為奇數。

預處理每個字元的字首和即可。複雜度 \(O(n)\)

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 10;
int c[N], o[N], w[N];
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	std::string s;
	std::cin >> s;

	s = "#" + s;
	int n = s.length();
	for (int i = 1; i <= n; i++) {
		c[i] = c[i - 1] + (s[i] == 'C');
		o[i] = o[i - 1] + (s[i] == 'O');
		w[i] = w[i - 1] + (s[i] == 'W'); 
	}	

	int q;
	std::cin >> q;
	while(q--) {
		int l, r;
		std::cin >> l >> r;

		int C = c[r] - c[l - 1], O = o[r] - o[l - 1], W = w[r] - w[l - 1];
		if(((C & 1) && !(O & 1) && !(W & 1)) || (!(C & 1) && (O & 1) && (W & 1))) std::cout << "Y";
		else std::cout << "N";
	}

	return 0;
}

相關文章