【问题描述】
一天,小 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
【数据范围】
对于 30%的数据,N 和 M <= 5000
对于 80%的数据,N 和 M <= 500000
对于 100%的数据,N 和 M <= 1000000
题解:找规律
一段区间的值只与其中0的个数有关,偶数个0为1,奇数个0为0。
#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; const int N=1e6+10; int n, m, sum[N], l, r; char s[N]; void Getin(int &shu){ char c;int f=1;shu=0; for(c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) shu=shu*10+c-'0'; shu*=f; } int main() { Getin(n); for( int i=1; i<=n; i++ ) Getin(sum[i]), sum[i]+=sum[i-1]; scanf( "%d", &m ); for( int i=1; i<=m; i++ ) { Getin(l); Getin(r); if( ( l-r+1-sum[r]+sum[l-1] )&1 ) printf( "0\n" ); else printf( "1\n" ); } return 0; }
也可以用线段树
,但对于人品不好的人,线段树会T掉。#include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; const int N=1e6+10; int n, m, l, r; struct node{ int l, r, num; }tree[N<<2]; void Getin(int &shu){ char c;int f=1;shu=0; for(c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) shu=shu*10+c-'0'; shu*=f; } int Azui( int a, int b ) { return ( a^b )^1; } void Build( int l, int r, int pos ) { tree[pos].l=l; tree[pos].r=r; if( l==r ) { Getin(tree[pos].num); return; } int mid=( l+r )>>1; Build( l, mid, pos<<1 ); Build( mid+1, r, pos<<1|1 ); tree[pos].num=Azui( tree[pos<<1].num, tree[pos<<1|1].num ); } int Find( int l, int r, int pos ) { if( tree[pos].r<l || r<tree[pos].l ) return -1; if( l<=tree[pos].l && tree[pos].r<=r ) return tree[pos].num; int numl=Find( l, r, pos<<1 ); int numr=Find( l, r, pos<<1|1 ); if( numl!=-1 && numr!=-1 ) return Azui( numl, numr ); if( numl==-1 && numr==-1 ) return -1; if( numl!=-1 ) return numl; else return numr; } int main() { Getin(n); getchar(); Build( 1, n, 1 ); scanf( "%d", &m ); for( int i=1; i<=m; i++ ) { Getin(l); Getin(r); printf( "%d\n", Find( l, r, 1 ) ); } return 0; }
[BZOJ3378]一套NOIP膜你题:膜拜azui
最新推荐文章于 2019-03-30 19:35:29 发布