问题描述
一天,小 A 给了 J·G 一道水题,J·G 一眼秒了,现在 J·G 想考考你们:
小 A 有 N 个灯,排成了一列,现在小 A 给出来一个叫做 azui 的奇葩操作,我们把开着的灯看作数字 1,把关着的灯看作数字 0,定义 0 azui 0 = 1,0 azui 1 = 0,1 azui 1 = 1, 1 azui 0 = 0。现在小 A 有 N 个问题 azui(l,r),表示询问从左往右的第 l 个灯向右一个一个 azui 到第 r 个灯的结果是什么。
输入
第1 行一个整数 N 表示序列的长度。
第2 行 N 个整数 Ai,每个数不是 0 就是 1,表示灯是关的还是开的。
第3 行一个整数 M 表示询问的个数。
第4~M+3 行,每行两个整数 l 和 r,表示询问 azui(l,r)。
输出
共 M 行,第 i 行回答第 i 个询问。
样例输入
5
1 0 1 0 1
5
2 3
3 4
4 5
1 3
1 4
样例输出
0
0
0
0
1
数据范围
对于 30%的数据,N和 M <= 5000
对于 80%的数据,N和 M <= 500000
对于 100%的数据,N和 M <= 1000000
分析
这个azui运算就是同或。相同的就是1,不同的就是0.即
bool azui(bool a,bool b){return a==b;}
我们可以枚举出同或的规律:
Example | Answer |
---|---|
0 0 | 1 |
0 1 | 0 |
1 0 | 0 |
1 1 | 1 |
0 0 0 | 0 |
0 0 1 | 1 |
0 1 0 | 1 |
0 1 1 | 0 |
1 0 0 | 1 |
1 0 1 | 0 |
1 1 0 | 0 |
1 1 1 | 1 |
然后我发现同或似乎与数的排列方式无关,与数组中的0的个数有关。也可以发现同或的结合律 (a⊙b)⊙c=a⊙(b⊙c) 你发现这个东西,其实是可减的,求一个前缀和然后减一下,求出来了。
源代码
#include<ctime>
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,l,r;
const int N=1000001;
bool azui(int x,int y){return x==y;}
bool a[N];
void get(int &a){
a=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
}
void get(bool &a){
char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();
if(ch=='0') a=0;
else a=1;
}
int main()
{
get(n);
for(int i=1;i<=n;i++)
get(a[i]);
for(int i=2;i<=n;i++)
a[i]=azui(a[i],a[i-1]);
get(m);
while(m--){
get(l);get(r);
printf("%d\n",l==1?a[r]:azui(a[l-1],a[r]));
}
}