zoukankan      html  css  js  c++  java
  • [CF1438D] Powerful Ksenia

    Description

    给定一个长度为 (n) 的序列 (a),每次可以选择 (3) 个不相同的下标 (i,j,k),计算 (a_i oplus a_j oplus a_k),赋值给 (a_i,a_j,a_k)。问是否能通过不超过 (n) 次操作,使得所有数相同,构造方案。

    Solution

    构造的核心思路是我们发现,如果有 (x,x,y) 这样的情况,那么操作一次就可以变成 (y,y,y)

    对于奇数长度的情况,比如 (a,b,c,d,e o x,x,x,d,e o x,x,y,y,y o y,y,y,y,y)

    对于偶数长度的情况,我们可以按照类似的方法进行构造,但是无论如何都会剩下一个数。

    考虑到这样的操作是不会影响整个序列的异或和的,因此我们只需要对前面 (n-1) 个数构成的序列进行操作,最后判定最后一个数与他们是否相等即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 1000005;
    
    int n,a[N];
    
    void solve(int n)
    {
        int i=1;
        cout<<n-2<<endl;
        while(i<n)
        {
            cout<<i<<" "<<i+1<<" "<<i+2<<endl;
            int tmp=a[i]^a[i+1]^a[i+2];
            a[i]=a[i+1]=a[i+2]=tmp;
            i+=2;
        }
        i-=2;
        while(i>1)
        {
            i-=2;
            cout<<i<<" "<<i+1<<" "<<i+2<<endl;
            int tmp=a[i]^a[i+1]^a[i+2];
            a[i]=a[i+1]=a[i+2]=tmp;
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
    
        int sum=0;
        for(int i=1;i<=n;i++) sum^=a[i];
    
        if(n%2==0)
        {
            if(sum==0)
            {
                cout<<"YES"<<endl;
                solve(n-1);
            }
            else 
            {
                cout<<"NO"<<endl;
            }
        }
        else 
        {
            cout<<"YES"<<endl;
            solve(n);
        }
    
        // DEBUG
        // for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        // cout<<endl;
    }
    
  • 相关阅读:
    Bellman-Ford(BF)和Floyd算法
    Dijkstra实现最短路径
    【图论】连通分量个数(并查集)
    【模拟】n a^o7 !
    【图论】最小生成树
    【搜索DFS】图的深度遍历(dfs)
    【搜索BFS】poj3278--Catch That Cow(bfs)
    【图论】判断给定图是否存在合法拓扑序列
    二叉排序树
    【树】判断给定森林中有多少棵树(简单做法)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13974707.html
Copyright © 2011-2022 走看看