• [CF743]D. Xor of 3


    这题只能说不看题解真写不出来(可能是因为我没有脑子吧...

    可以证明一下题解:

    1.如果所有数异或起来不为0,则输出NO

    首先我们发现三个数里面之后有一个1的时候,会变成三个1。如果有两个1的话,会变成0个1。我们发现其奇偶性是不会改变的。

    2. 对于奇数情况,我们先选择 1, 3, 5, ..., n-2,之后选择n-4, n-6, ...., 3, 1。

    首先如果选择 1, 3, 5, ..., n-2的话,能保证an, an-1, an-2都是0, 并且对于所有的偶数位置, ai = ai-1。

    给出证明:

      如果奇数个数异或起来为0的话,这说明有偶数个1,以及奇数个0。

      因为操作不改变奇偶性,所以一定会存在011或者000这种情况,操作之后就变成000了,之后一旦出现000这种情况之后,后面其实就都是0了。

      之后这样选择之后,剩下的数列就变成了ai = ai-1。 (可以操作看看

    (证毕

    于是剩下的都是连续的11,之后我们倒着操作就行了。

    3. 对于偶数情况,我们只需要将他分成两个奇数情况,就可以了。如果没有就输出NO。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    const int inf = 0x3f3f3f3f; ///1061109567
    const int maxn = 2e6 + 10;
    
    int n;
    vector<int> opt;
    int a[maxn];
    
    void solve(int l, int r) {
        for (int i = l; i+2 <= r; i += 2) opt.push_back(i);
        for (int i = r-4; i >= l; i -= 2) opt.push_back(i);
    }
    
    void print() {
        puts("YES");
        printf("%d
    ", opt.size());
        for (auto i : opt) printf("%d ", i);
        puts("");
    }
    
    int main() {
        int T; scanf("%d", &T);
        while (T--) {
            opt.clear();
            int n; scanf("%d", &n);
            int sum = 0;
            for (int i = 1; i <= n; ++ i) {
                scanf("%d", &a[i]);
                sum ^= a[i];
            }
            if (sum == 0) {
                if (n % 2) {
                    solve(1, n);
                    print();
                }
                else {
                    sum = 0;
                    for (int i = 1; i <= n; ++ i) {
                        sum ^= a[i];
                        if (i % 2 == 1 && sum == 0) {
                            solve(1, i);
                            solve(i+1, n);
                            print();
                            break;
                        }
                        if (i == n) puts("NO");
                    }
                }
            } else puts("NO");
        }
        return 0;
    }
    /*
    5
    5
    0
    0
    1 1
    2 5 3
    1 1
    */
  • 相关阅读:
    java MVC设计模式探究——mvc在JAVA应用程序中的应用
    datagridview 的Columns 点击列标题 禁止排序
    组合键事件
    对一段视频,采帧(总结)
    datagridview中加入checkbox列,全选问题
    微软的RDLC报表(转)
    Linq to sql直接执行sql语句(转)
    获取当月的第1天
    AxWindowsMediaPlayer的详细用法
    DataSet
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/15327964.html
Copyright © 2020-2023  润新知