645 字
3 分钟
与非
2017-08-08

题目描述#

作为一名新世纪共产主义的接班人,你认识到了资本主义的软弱性与妥协性,决定全面根除资本主义,跑步迈入共产主义。但是当你即将跨入共产主义大门的时候,遇到了万恶的资本家留下的与非电路封印,经过千辛万苦的研究,你终于把复杂的破解转变成了以下问题:

初始时你有一个空序列,之后有N个操作。

操作分为一下两种:

1 x:在序列末尾插入一个元素x(x=0或1)。

2 L R:定义nand[L,R]为序列第L个元素到第R个元素的与非和,询问nand[L,L]^nand[L,L+1]^nand[L,L+2]^…^nand[L,R]。

Nand就是先与,再取反

输入#

从文件nand.in中读入数据。

输入第一行一个正整数N,表示操作个数。

接下来N行表示N个操作。

为了体现程序的在线性,记lastans为上一次操作二的回答,初始lastans=0,。对于操作1,你需要对x异或lastans。对于操作二,设现在序列中的元素个数为M,如果lastans=1,那么你需要作如下操作:L=M-L+1,R=M-R+1,swap(L,R)

输出#

输出到nand.out中。

输出有多行。为对于每一个操作二的回答。

样例输入#

6
1 1
1 1
1 0
2 1 2
2 1 3
2 2 3

样例输出#

1
0
0

【数据规模和约定】#

数据点 N的规模 操作一的个数M1 操作二的个数M2

1 N<=1000 M1<=500 M2<=500 2 N<=1000 M1<=500 M2<=500 3 N<=200000 M1<=100000 M2<=100000 4 N<=200000 M1<=100000 M2<=100000 5 N<=1000000 M1<=900000 M2<=100000 N<=4000000 M1<=3900000 M2<=100000

题解#

想了好久 也没想出来 最后放弃了

其实可以分类讨论

最后会发现一个结论

#include <cstdio>
#include <algorithm>
#include <cstdlib>
using namespace std;
inline int read()
{
    int s = 0, k = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
        k = ch == '-' ? -1 : k, ch = getchar();
    while (ch >= '0' && ch <= '9')
        s = s * 10 + (ch ^ 48), ch = getchar();
    return s * k;
}
int n;
bool Sum[4000005];
bool f[4000005];
bool a[4000005];
int main()
{
    n = read();
    int t = 0, op, l, r;
    int lastans = 0;
    while (n--)
    {
        op = read();
        if (op == 1)
        {
            l = read() ^ lastans;
            t++;
            a[t] = l;
            if (t == 1)
                f[t] = a[t];
            else
                f[t] = !(f[t - 1] & l);
            Sum[t] = Sum[t - 1] ^ f[t];
        }
        else
        {
            l = read(), r = read();
            if (lastans)
            {
                l = t - l + 1;
                r = t - r + 1;
                swap(l, r);
            }
            lastans = a[l];
            int i = l, now = !(a[l] & a[l + 1]);
            while (now != f[i + 1] && i < r)
            {
                lastans ^= now;
                i++;
                now = !(now & a[i + 1]);
            }
            if (i < r)
            {
                lastans ^= Sum[r] ^ Sum[i];
            }
            printf("%d\n", lastans);
        }
    }
    //while (1);
}

与非
https://www.nekomio.com/posts/78/
作者
NekoMio
发布于
2017-08-08
许可协议
CC BY-NC-SA 4.0