USACO22OPEN-Silver C
前言(Front talk)
网址(Website)
题目(Problem)
选择两个相邻相等的字母并将其删除。
选择一个字母,将其替换为另外两个字母的任一排列。
求出这个字符串本身的答案对
输入格式(Input)
输入的第一行包含
第二行包含
以下
输出格式(Output)
输出一个长为
样例(Example)
样例输入
COW
6
1 1
1 2
1 3
2 2
2 3
3 3
样例输出
YNNNYN
提示(Notice)
【样例解释】
第一个询问的答案是「是」,因为 s 的第一个字符已经等于 ‘C’。
第五个询问的答案是「是」,因为 s 的第二到第三个字符组成的子串 OW 可以通过两步操作变为 ‘C’:
OW
-> CWW
-> C
这个样例字符串 COW 的其他子串均不能被转变为 ‘C’。
【测试点性质】
- 测试点
满足 以及 。 - 测试点
没有额外限制。
题解(Solution)
容易得到几个性质:
- 任两个字母可以交换
- 任两个不同字母可以合成一个字母
- 任两个相等字母可以抵消
然后直接记录三个字母的前缀数量,到时候直接差分求字母数,
代码(Code)
#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
inline int input(){int x;return cin>>x,x;}
const int N = 201234;
char a[N];
int n,q;
int c[N],o[N],w[N];
inline bool check(int l,int r){
int C=(c[r]-c[l-1])%2;
int O=(o[r]-o[l-1])%2;
int W=(w[r]-w[l-1])%2;
if(C==1 && O==0 && W==0) return true;
if(C==0 && O==1 && W==1) return true;
return false;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string str("cowoper");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
cin>>(a+1)>>q;
n=strlen(a+1);
For(i,1,n){
c[i]=c[i-1],o[i]=o[i-1],w[i]=w[i-1];
if(a[i]=='C') c[i]++;
if(a[i]=='O') o[i]++;
if(a[i]=='W') w[i]++;
}
while(q--){
int l=input(),r=input();
cout<<(check(l,r)?'Y':'N');
}return 0;
}