zoukankan      html  css  js  c++  java
  • 【CF1438D】Powerful Ksenia

    题目

    题目链接:https://codeforces.ml/problemset/problem/1438/D
    (n) 个正整数 (a_i),(1 le a_ile10^9)

    每次操作是选三个不同的下标 (i,j,k) ,让 (a_i,a_j,a_k) 都变成 (a_i oplus a_joplus a_k) 也就是这三个数的异或和。

    让你判断是否能在 (n) 次操作内,使这 (n) 个正整数的值变成相同的。

    若能,第一行输出YES,第二行输出 (m) 表示操作数两,接下来 (m) 行每行三个整数,描述一次操作;

    若不能,输出NO。

    思路

    由于 (aoperatorname{xor} boperatorname{xor} b=a),所以当 (n) 是奇数的时候,考虑将序列变为 (frac{n-1}{2}) 个两两相等的数,再将他们全部异或上最后一个数。
    那么我们每次取任意三个数异或起来,将其中两个放做一组,剩余一个扔进序列中继续搞,这样就可以在 (frac{n-1}{2}) 次操作达到目标。最后异或成同一个数仍然需要 (frac{n-1}{2}) 次操作,总操作数为 (n-1) 次。
    (n) 是偶数的时候,因为进行任意操作序列的异或和仍然不变,所以最终如果有解,序列异或和一定是 (0)
    所以如果原序列异或和不为 (0) 直接无解,否则我们可以先将前 (n-1) 个数字按照奇数的方式做好,第 (n) 个数字最终一定等于第 (n-1) 个数字。操作次数为 (n-2)
    时间复杂度 (O(n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int n,xors;
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1,x;i<=n;i++)
    	{
    		scanf("%d",&x);
    		xors^=x;
    	}
    	if (!(n&1) && xors) return printf("NO"),0;
    	if (!(n&1)) n--;
    	printf("YES
    %d
    ",n-1);
    	for (int i=1;i<=n-2;i+=2)
    		printf("%d %d %d
    ",i,i+1,i+2);
    	for (int i=1;i<=n-2;i+=2)
    		printf("%d %d %d
    ",i,i+1,n);
    	return 0;
    }
    
  • 相关阅读:
    垂直渐变的Button
    winform下重画ListBox
    分享一个 C# Winfrom 下的 OutlookBar 控件的使用
    颜色下拉菜单(combox)
    Robot Framework 使用技巧 快捷键
    Batch 拷贝远程机器文件到本机指定目录下
    JMeter常用函数 使用图解
    SoapUI报ClientProtocolException错误
    Setup Script in SoapUI
    邮件自动回复
  • 原文地址:https://www.cnblogs.com/stoorz/p/13998340.html
Copyright © 2011-2022 走看看