【原创】【一套NOIP膜你赛】【大水题】第一题 膜拜azui

膜拜azui

题目

膜拜 azui

(azui.cpp/c/pas)

【问题描述】

一天,小 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

分析

讲讲我的心路历程。
首先这个a azui b运算就是return a==b,它有一个专业术语,叫做同或
在考试的时候,我前半个小时完全没有思路,写一个暴力程序然后看着它发呆。兰后我掏出了一个草稿本,手动全排列来计算azui值。
如下:

000 0
001 1
010 1
100 1
011 0
101 0
110 0
111 1

以此类推,把4枚举到一半,发现,哇,好有规律呀!!
我发现了规律1:同或有结合律。也就是说,给定数量的0和1,最后的结果总是固定的,与顺序无关
这个也很好证明,分类讨论就行了。

于是我写了个程序打表:
这里写图片描述

括号里左边是0的数量,右边是1的数量。
横着看,000000000,11111111,000000000,1111111111,0000000……
博主又在中八了
我们可以发现规律2:同或的结果取决于0的数量,值可能大概应该也许就一定是零的个数模2取反。
然后就简单了,用个前缀和来保存零的个数,然后直接 Θ(1) 的时间复杂度求。

代码

#include<cstdio>

void Read(int &p)
{
    p=0;
    int f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
        p=p*10+c-'0',c=getchar();
    p*=f;
}

int N,M,sig0[1002017],a[1002017],l,r;

int main()
{
    freopen("azui.in","r",stdin);
    freopen("azui.out","w",stdout);

    sig0[0]=0;
    Read(N);
    for(int i=1;i<=N;i++) 
        Read(a[i]),sig0[i]=sig0[i-1]+(a[i]^1);
    Read(M);

    for(int i=1;i<=M;i++) 
    {
        Read(l),Read(r);
        if(l==r) printf("%d\n",a[l]);
        else printf("%d\n",!((sig0[r]-sig0[l-1])%2));
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值