我写了一个大常数的O(nlogn)算法在洛谷上过了,然后在usaco上交就没跑过。 算法是瞎想的因为没找到什么特别好的规律
代码是这样的:
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
string s;
int q;
const int maxs = 2e5+10;
int f[maxs][20];
int judge(int a,int b)
{
if(b < a)
{
swap(a,b);
}
if(a == b)
{
return 0;
}
else if((a == 0 && b == 1)|| (a == 2 && b ==3))
{
return 1;
}
else if((a == 0 && b == 2)|| (a == 1 && b ==3))
{
return 2;
}
else
return 3;
}
void init()
{
for(int i=0;i<s.size();i++)
{
if(s[i] == 'C')
{
f[i+1][0] = 1;
}
else if(s[i] == 'O')
{
f[i+1][0] = 2;
}
else
{
f[i+1][0] = 3;
}
}
for(int j = 1;j<=20;j++)
{
for(int i=1;i<=s.size();i++)
{
if(i+pow(2,j)-1<=s.size())
{
f[i][j] = judge(f[i][j-1],f[i+(int)pow(2,j-1)][j-1]);
}
}
}
}
int proc(int x,int y)
{
int ans = 0;
int num = y-x+1;
int curr = x;
for(int i = 18;i >= 0;i--)
{
if(num >= (int)pow(2,i))
{
num = num - (int)pow(2,i);
ans = judge(ans,f[curr][i]);
curr = curr + (int)pow(2,i);
}
}
return ans;
}
int main()
{
getline(cin,s);
init();
cin>>q;
for(int i=1;i<=q;i++)
{
int x,y;
cin>>x>>y;
int result = proc(x,y);
if(result == 1)
{
cout<<"Y";
}
else
{
cout<<"N";
}
}
return 0;
}