P7362 [eJOI 2020 Day2] XOR Sort

题意

给你一个长度为 \(n\) 的序列,每次操作可以将一个数异或上相邻的一个数,求将序列改为严格单调递增序列或严格单调不降序列的操作次数的操作序列。

注意,改为严格单调递增序列的数据 \(n\leq 200\) 且每个数不相同,改为严格单调不降序列的数据 \(n\leq 1000\)。

不要求操作次数最小,次数需不大于 \(40000\),元素大小小于 \(2^{20}\)。

思路

严格单调递增序列的数据实测如果改了数列很容易造成数字相同然后挂掉的情况出现。反而严格单调不降的条件用异或容易满足且数据范围大。我们考虑对数据分治。

  • 严格单调递增序列

我们考虑冒泡排序的思想,每次用异或交换相邻两项,可以过第一档部分分。

考虑优化这个过程。考虑每次将一个最大的数换到序列最后的方法。设

\[A=\{a,b,c,d,e,f,g\}
\]

若此时 \(d\) 是最大的数,我们想把它换到最后面,设 $\oplus $ 表示二进制异或操作,我们可以先将序列变为

\[\{a\oplus b,b\oplus c,c\oplus d,d\oplus e,e\oplus f,f\oplus g,g\}
\]

对于 \(d\oplus e\) 后面的元素,我们将它们按顺序与前一项异或,容易发现序列变为

\[\{a\oplus b,b\oplus c,c\oplus d,d\oplus e,d\oplus f,d\oplus g,d\}
\]

那么我们就将 \(d\) 换到队尾去了。为了消除 \(d\) 的影响,我们将前面的元素也进行类似的操作

\[\{a\oplus d,b\oplus d,c\oplus d,d\oplus e,d\oplus f,d\oplus g,d\}
\]

此时对于缩小了一个长度的序列重复进行求解即可。注意每次寻找的是原数列上的最大值而非每次更新完后的值。

操作次数为 \(\frac 12\times 2n^2=n^2\)。

  • 严格单调不降序列

从高位向低位考虑,每次我们仅考虑序列这一位的数,若非全 \(0\) 则一定能通过异或将其变为只剩一个 \(1\) 。从左往右考虑清零,若 \(a_i\) 该位为 \(1\),那么我们让 \(a_{i+1}\oplus a_i\) 使该位为 \(1\)(若本为 \(1\) 则不操作)。操作完后使最后一位为 \(1\),并将序列长度减 \(1\)(结尾位置前移)。

注意当有一位为全 \(0\) 的时候我们不能将序列长度缩短,因为我们保证序列单调不降的方法是后面的最高位二进制位数比前面的大,全 \(0\) 的话会导致不满足并被卡。虽然实际上该题数据没有卡这个。

实现

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
#include<utility>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=1005;
int n,a[maxn];
int Ans;
pair<int,int> ans[1000005];
inline void work1(){
static int b[maxn];
for(int i=1;i<=n;i++) a[i]=b[i]=read();
for(int len=n-1;~len;len--){
int x=0;
for(int i=1;i<=len+1;i++) if(b[i]>b[x]) x=i;
for(int i=1;i<=len+1 and i<n;i++) a[i]^=a[i+1],ans[++Ans]=make_pair(i,i+1);
for(int i=x;i<=len;i++) a[i+1]^=a[i],ans[++Ans]=make_pair(i+1,i),swap(b[i],b[i+1]);
for(int i=x-1;i>1;i--) a[i-1]^=a[i],ans[++Ans]=make_pair(i-1,i);
}
}
inline void work2(){
for(int i=1;i<=n;i++) a[i]=read();
for(int cnt=0,k=19;~k;k--){
bool ok=false;
for(int i=1;i<=n-cnt;i++) ok|=(a[i]>>k)&1;
if(!ok) continue;
for(int i=1;i<n-cnt;i++) if((a[i]>>k)&1){
if((a[i+1]>>k)&1^1) a[i+1]^=a[i],ans[++Ans]=make_pair(i+1,i);
a[i]^=a[i+1],ans[++Ans]=make_pair(i,i+1);
}
++cnt;
}
}
}
signed main(){
star::n=read();
if(read()==1) star::work1();
else star::work2();
printf("%d\n",star::Ans);
for(int i=1;i<=star::Ans;i++) printf("%d %d\n",star::ans[i].first,star::ans[i].second);
return 0;
}

P7362 [eJOI 2020 Day2] XOR Sort的更多相关文章

  1. 「JOISC 2020 Day2」变态龙之色 题解

    题目传送门 注意 同性必定不同色 必有一个同色异性,且不相互不喜欢 Solution 我们发现,我们问题比较大的就是如何确定性别问题.我们可以一个一个加进去,在原来已经确定了的二分图上增加新的性别关系 ...

  2. 洛谷P7167 [eJOI 2020 Day1] Fountain (单调栈+ST)

    开两个数组:to[i][j]表示从i这个位置向下的第2j个圆盘是哪个,f[i][j]表示流满从i这个位置向下的 2j 个圆盘需要多少体积的水. 详情见代码: 1 #include<bits/st ...

  3. JavaScript:sort() 方法

    ylbtech-JavaScript:sort() 方法 JavaScript sort() 方法 1. 定义和用法返回顶部 sort() 方法用于对数组的元素进行排序. 语法 arrayObject ...

  4. hihoCoder挑战赛28 题目1 : 异或排序

    题目1 : 异或排序 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个长度为 n 的非负整数序列 a[1..n] 你需要求有多少个非负整数 S 满足以下两个条件: ...

  5. Js 数组对象排序

    1.定义函数 /** * 数组对象排序函数 * @param {any} name 排序字段 * @param {any} order 升.降(这里事true.false记得处理下) */ var b ...

  6. 2020 CCPC-Wannafly Winter Camp Day2

    2020 CCPC-Wannafly Winter Camp Day2 A 托米的字符串 虽然每个子串出现的概率是相同的,但是同一长度的子串个数是不同的,所以要分别处理.计算出某一长度的情况下,元音字 ...

  7. Wannafly Winter Camp 2020 Day 5J Xor on Figures - 线性基,bitset

    有一个\(2^k\cdot 2^k\) 的全零矩阵 \(M\),给出 \(2^k\cdot 2^k\) 的 \(01\) 矩阵 \(F\),现在可以将 \(F\) 的左上角置于 \(M\) 的任一位置 ...

  8. 清北学堂 2020 国庆J2考前综合强化 Day2

    目录 1. 题目 T1 一 题目描述 Sol T2 二 题目描述 Sol T3 三 题目描述 Sol T4 四 题目描述 Sol 2. 算法 -- 数据结构 1. 题目 T1 一 题目描述 问题描述 ...

  9. 训练计划Day2

    Day2:线段树(可持久化),平衡树(splay,treap),并查集,树链剖分,动态树,树状数组,点分治(可持久). 线段树模板 //区间最大,and,or #include <cstdio& ...

随机推荐

  1. httprunner 2.5.7 下.env 文件环境变量的使用及debugtalk的使用,对test的参数化及执行

    一.httprunner 2.5.7 下.env  文件的使用 1..env 文件配置如下: 2.debugtalk.py 编写如下: 在debugtalk.py中增加开始和结束执行语句: 3.需要做 ...

  2. JMeter执行方式

    JMeter执行方式有2种,一种是GUI模式,一种是NO-GUI模式. GUI模式就是界面模式,如下: NO-GUI模式就是命令行模式. 界面模式主要用来编写和调试脚本用的,项目的真正执行最好是采用命 ...

  3. 04:全局解释器锁(GIL)

    1 全局解释器锁(GIL) 0 pypy(没有全局解释器锁) cpython(99.999999%)    -pypy python好多模块用不了,1 全局解释器锁,GIL锁(cpython解释器的问 ...

  4. Echarts的使用教程

    项目中需要使用图表,最初使用的.NET自带的MSChart控件,做出来的效果不太好,所以又使用了Echarts控件. MSChart源码放在最后,可自行下载查看. Echarts是一个基于 JavaS ...

  5. Webflux请求处理流程

    spring mvc处理流程 在了解SpringMvc的请求流程源码之后,理解WebFlux就容易的多,毕竟WebFlux处理流程是模仿Servlet另起炉灶的. 下面是spring mvc的请求处理 ...

  6. 【模拟8.09】建设城市(city) (容斥)

    放在了考试T1 发现70分的DP很水啊,f[i][j]为当前位置是i分配了j个队的方案 我们用前缀和统计,在将i删去,j倒序枚举,就可以删掉一维(也可以滚动数组滚起来) 1 #include<i ...

  7. ClickHouse学习系列之五【系统库system说明】

    背景 之前介绍过ClickHouse相关的系列文章,现在ClickHouse已经能正常使用起来了,包括副本和分片.因为ClickHouse已经可以提供服务了,现在需要关心的就是服务期间该数据库的各项性 ...

  8. STL----vector注意事项

    开vector时要注意内存容易炸 最好的办法就是在开vector之后,对他进行一步操作 vector<int> a; a.resize(n); n就是你要开的数组的大小,此时数组里已经插入 ...

  9. Java小工具类

    计时器(秒表),计算程序运行时间用的 public class Stopwatch { private static long startTime=0; private static long end ...

  10. 9、ssh服务详解及优化

    ssh是"secure shell protocol"的简写,在进行数据传输之前,ssh先对练级数据包通过加密技术进行加密处理, 加密后再进行数据的传输,从而确保了数据的安全: s ...