E. 开还是关,这是一个问题
本题时间限制为3s
Description
话说有n个开关,编号1到n,初始时都是关的,但由于喵呜的贪玩,有一些开关被喵呜给打开了,现在喵呜想要复原这些开关。但喵呜觉得如果只是把开的给关掉就不能显得他有多么的神,于是,他决定每一次就将a,b之间(包括a,b)的开关调到相反的状态(即开变关,关变开),但是经过多次后,他忘了编号为k的开关的状态,他希望你能帮他解决
Input
输入包括多组数据,每组数据第一行是一个整数n(n<=10^6)
接下来一行有n个整数,代表开关的状态,分别用0,1表示(0表关,1表开)
接下来一个整数m(m<=10^6)
接下来m行,每一行代表一个操作
C a b 将a b之间的开关调到相反状态
Q k 询问编号为k的开关的状态
Output
对于每组数据的询问,输出一行,用0或1表示k开关的状态
Sample Input
5
0 0 1 0 0
3
Q 4
C 2 4
Q 4
Sample Output
0
1
暴力:(时间多)
#include <stdio.h>
int s[1000010];
int main()
{
int i,m,n,a,b;
char t[10];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&s[i]);
scanf("%d%*c",&m);
while(m--)
{
scanf("%s",t);
if(t[0]=='Q')
{
scanf("%d",&a);
printf("%d\n",s[a]%2);
}
else
{
scanf("%d%d",&a,&b);
for(i=a;i<=b;i++)
s[i]++;
}
}
return 0;
}
树状数组:(貌似时间最短)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 1000010;
int tree[maxn];
int n;
inline int Lowbit(int x) {
return x & (-x);
}
inline void Update(int pos, int val) {
while (pos <= n) {
tree[pos]=(tree[pos] + val)%2;
pos += Lowbit(pos);
}
}
inline int Query(int x) {
int sum = 0;
while (x > 0) {
sum=(sum + tree[x])%2;
x -= Lowbit(x);
}
return sum;
}
int main()
{
while (~scanf("%d", &n))
{
memset(tree, 0, sizeof(tree));
int i,j,x;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
if(x)
Update(i,1),Update(i+1,1);
}
int m;
scanf("%d",&m);
while(m--)
{
char s[5];
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d",&x);
printf("%d\n", Query(x)%2);
}
else
{
int a, b;
scanf("%d%d", &a, &b);
Update(b+1 ,1);
Update(a, 1);
}
}
}
return 0;
}
线段树:(模版)。。。。其实我套了半天。。。。
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct Tree
{
int l,r,num,num1,lazy;
}tree[6000000];
int a[1000000];
char str[10];
void build(int t,int x,int y)
{
tree[t].l=x;
tree[t].r=y;
tree[t].num1=0;
if(x==y)
{
tree[t].num=a[x];
return ;
}
int mid=(x+y)/2;
build(2*t+1,x,mid);
build(2*t+2,mid+1,y);
tree[t].num=tree[2*t+1].num+tree[2*t+2].num;
}
void add(int t,int x,int y,int val)
{
int l=tree[t].l;
int r=tree[t].r;
if(l==x&&y==r)
{
tree[t].lazy=1;
tree[t].num1+=val;
tree[t].num+=val*(l-r+1);
return ;
}
int mid=(l+r)/2;
if(tree[t].lazy==1)
{
tree[t].lazy=0;
add(2*t+1,l,mid,tree[t].num1);
add(2*t+2,mid+1,r,tree[t].num1);
tree[t].num1=0;
}
if(x<=mid) add(2*t+1,x,min(y,mid),val);
if(y>mid) add(2*t+2,max(mid+1,x),y,val);
tree[t].num=tree[2*t+1].num+tree[2*t+2].num;
}
int query(int t,int x,int y)
{
int l,r,mid,ans;
l=tree[t].l;
r=tree[t].r;
if(l==x&&y==r)
{
return tree[t].num;
}
mid=(l+r)/2;
if(tree[t].lazy==1)
{
tree[t].lazy=0;
add(2*y+1,l,mid,tree[t].num1);
add(2*t+2,mid+1,r,tree[t].num1);
tree[t].num1=0;
}
ans=0;
if(x<=mid) ans+=query(2*t+1,x,min(mid,y));
if(y>mid) ans+=query(2*t+2,max(mid+1,x),y);
return ans;
}
int main()
{
int m,n,t,b;
scanf("%d",&m);
for(int i=0;i<m;i++)
scanf("%d",&a[i]);
build(0,0,m-1);
scanf("%d",&n);
while(n--)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d",&t);
printf("%d\n",query(0,t-1,t-1)%2);
}
else
{
scanf("%d%d",&t,&b);
add(0,t-1,b-1,1);
}
}
return 0;
}