round #618 div2 C(文末有技巧)

这是题目链接->链接

题目:

原题目是全英文的,所以我就粗略来翻译一下:

有这样一个函数f:f(x,y)=(x|y)-y;(其中|是按位或操作)

比如说:f(11,6)=(11|6)-6=15-6=9;(简单明了)

现在有一个数组 [a1,a2,…,an],让你求f(f(…f(f(a1,a2),a3),…an−1),an) ,数组中可能有相同的数字,让你对这个数组重新排序,以保证最终的结果是最大。(如果有多个答案,输出任意一种即可)

样例输入输出

输入

第一行输入一个n(1≤n≤10^5).

第二行输入n个数,a1,a2,…,an (0≤ai≤10^9).

输出

输出n个数,最后结果是最大的数组顺序,如果有多个答案,任意输出一种。

样例输入

4

4 0 11 6

样例输出

11 6 4 0

样例输入

1

13

样例输出

13

思路

我就不说我的思路了(萌新思路),官方题解+正规解答是这个样子的:

首先观察题目函数f(11,6)=11|6-6,既然是关于位操作的,那么来一波二进制运算:

11:1011

    6:0110

ans:1001

  ~6:1001

最后经过大佬的慧眼(不是我),得出结论为

f(x|y)=(x|y)-y=x&(~y)!!!

ps:

~为取反操作,1变0,0变1,如0110(6),1001(~6)

&为按位与操作,有0则0,无0则1,如1011(11)&1001(~6)=1001

所以[a1,a2,…,an]就变成了a1&(~a2)&(~a3)....&(~an);

根据官方题解来讲a1对答案贡献最大(我觉得a1最为特殊),找到a1,其他的依次输出就可以了,找不到就原序输出;

那么问题来了,如何找到那个扛把子a1?

据大佬口述,只需要找到最高位的1在谁那,谁就是扛把子

那么思路油然而生️:

从最高位二进制最高位遍历每个数,一旦找到一个,就是a1,把它首先输出,再把其它的数依次输出,如果找不到,就原序输出:

#include <iostream>
#include <cstdio>
#define N 100005
using namespace std;
//@date: 2020-02-10 11:28:12
//@state:Yes
//@purpose:bitmasking(位屏蔽) inline void read(int &x){
//快速读取int
int ch = getchar(); x = 0;
bool f = false;
while((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if(ch == '-'){f = true; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
if(f) x = -x;
} int a[N],c[N]; int main()
{
int n;
read(n);
for(register int i=1;i<=n;i++)
read(a[i]);
for(register int j=30;j>=0;j--)
{
int cnt=0,p;
for(register int i=1;i<=n;i++)
if((a[i]>>j)&1)//把a[i]右移j位就是取a[i]的第j+1位二进制数,看是否是1}
cnt++,p=i;
if(cnt==1)
{
cout<<a[p]<<" ";//输出扛把子a1
for(register int k=1;k<=n;k++)
{//输出其他的
if(k!=p)
cout<<a[k]<<" ";
}
return 0;
}
}
//没找到扛把子的情况,就原序输出
for(register int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}

小技巧(拿小本本记下来)

  • 快速读取数字,实测比最快的scanf还要快!
inline void read(int &x){
int ch = getchar(); x = 0;
bool f = false;
while((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if(ch == '-'){f = true; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
if(f) x = -x;
}
  • 二进制的遍历

有人可能会问,为什么遍历二进制数j要从30开始,到0呢?

且听我细细道来~

首先int类型(指有符号整型),现在都是4字节32位了,所以范围就是-2^32 -1到2^32-1,也就是说最长为31位,剩下一位表示正负,我们不用管。

我们想要的就是从二进制最高位去遍历

而右移>>符号的意思正好满足我们获取最高位的功能

比如说:1011(11)

11>>3=1011(1),现在右移3位得到的就是第4位二进制数。

  • bitmasking(位屏蔽)

位屏蔽的含义是从包含多个位集的一个或一组字节中选出指定的一(些)位。为了检查一个字节中的某些位,可以让这个字节和屏蔽字(bit mask)进行按位与操作(C的按位与运算符为&)——屏蔽字中与要检查的位对应的位全部为1,而其余的位(被屏蔽的位)全部为0。

以上是来自百度回答,这个名词百度百科中没有,但是我觉得这个回答很好。

但是你们是不是看的头疼啦(是的,啥也没看懂-.-),简而言之,取出二进制数的特定位来操作。

放在这道题上就是取出a[i]的第j+1位二进制数判断是否是1,用代码来说就是这个地方:

if((a[i]>>j)&1)//把a[i]右移j位就是取a[i]的第j+1位二进制数,看是否是1}
  • 使用频繁的变量放在寄存器

register int的register表示使用cpu内部寄存器(寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件)的变量,而平时的int是把变量放在内存中,存到寄存器中可以加快变量的读写速度)

for(register int i=1;i<=n;i++)
read(a[i]);

现在有人说C++最新标准已经不认这个了,反正我自己使用做对比仍有提升(现在时间2020.2.10),在多重循环中颇有奇效!!!嘘~这是我从这次比赛榜一的代码中学到的,自己知道就行了️

【CF】Round #618 div2 C(文末有技巧)的更多相关文章

  1. CF Round #580(div2)题解报告

    CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...

  2. CF round #622 (div2)

    CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...

  3. [CF Round #295 div2] C. DNA Alignment 【观察与思考0.0】

    题目链接:C. DNA Alignment 题目大意就不写了,因为叙述会比较麻烦..还是直接看英文题面吧. 题目分析 经过观察与思考,可以发现,构造的串 T 的每一个字符都与给定串 S 的每一个字符匹 ...

  4. [CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】

    题目链接:E. A and B and Lecture Rooms 题目大意 给定一颗节点数10^5的树,有10^5个询问,每次询问树上到xi, yi这两个点距离相等的点有多少个. 题目分析 若 x= ...

  5. [CF Round #294 div2] D. A and B and Interesting Substrings 【Map】

    题目链接:D. A and B and Interesting Substrings 题目大意 给定26个小写字母的权值,一共26个整数(有正有负). 给定一个小写字母组成的字符串(长度10^5),求 ...

  6. A. Grasshopper And the String(CF ROUND 378 DIV2)

    A. Grasshopper And the String time limit per test 1 second memory limit per test 256 megabytes input ...

  7. A. Alyona and Numbers(CF ROUND 358 DIV2)

    A. Alyona and Numbers time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. CF Round#436 div2

    额,这次的题目其实挺智障的.所以通过这次比赛,我也发现了自己是一个智障.... 不说太多,说多是泪... A. Fair Game 题意:给你一个数组,看你能否把它均分为两个所有元素均相同的子数组. ...

  9. CF Round #569 Div2(contest1180)

    比赛链接:http://codeforces.com/contest/1180 Problem A 题意:给出n,问方块数.看图理解... Solution: 找一找规律就可以了,发现方块数为2n*( ...

  10. CF Round #687 Div2 简要题解

    题面 A 可以发现,最远的几个人一定是 \((1, 1), (1, m), (n, 1), (n, m)\) 中的一个,直接计算即可. B 注意到颜色数量很少,直接暴力枚举最终的颜色后模拟即可. C ...

随机推荐

  1. Java-14流Stream【创建一个简易for循环工具】

    Java-14流Stream 构造简易的循环取代for IntStream类提供了一个range()方法,可以生成一个流----由int值组成的序列 import static java.util.s ...

  2. docker mysql8.0 启动,挂数据卷,定时备份,恢复~

    安装mysql 从mysql社区版的官方源去拉取镜像:mysql/mysql-server - Docker Image | Docker Hub docker run --name=mysql1 - ...

  3. CSP2022-S游寄

    游寄游寄,顾名思义,边游边寄 11.00AM 起床 复习了一下各种终端命令,然后又复习了一下对拍 虽然都没用到 然后接着睡. 有点小紧张,毕竟一年没搞OI 12.00AM 今天吃河虾 还行,只是有点扎 ...

  4. 卡特兰路径和q,t-enumeration 学一半的笔记

    目录 卡特兰 The1st q-analogue of \(C_n\) The 2nd q-analogue of \(C_n\) /定义\(C_n(q)\) The q-Vandermonde co ...

  5. 表现标准语言CSS3学习 入门+导入方式

    表现标准语言CSS3学习 入门+导入方式 如何学习: css是什么 css怎么用(快速入门) css选择器(重点+难点) 美化网页(文字.阴影.超链接.列表.渐变...) 盒子模型 浮动 定位 网页动 ...

  6. HTML+JS+CSS实现图片文件上传界面设计的例子

    在Java Web应用程序设计中文件上传功能的实现是一项非常重要的工作,本文中的例子程序实现了文件上传功能的界面设计.在Java Web应用程序设计中涉及到上传图片文件功能时,往往都需要对图片文件进行 ...

  7. 【原理揭秘】Vite 是怎么兼容老旧浏览器的?你以为仅仅依靠 Babel?

    作者:京东科技 孙凯 一.前言 对前端开发者来说,Vite 应该不算陌生了,它是一款基于 nobundle 和 bundleless 思想诞生的前端开发与构建工具,官网对它的概括和期待只有一句话:&q ...

  8. Python 人工智能 5秒钟偷走你的声音

    介绍 Python 深度学习AI - 声音克隆.声音模仿,是一个三阶段的深度学习框架,允许从几秒钟的音频中创建语音的数字表示,并用它来调节文本到语音模型,该模型经过培训,可以概括到新的声音. 环境准备 ...

  9. Algorithm参数记录

    一.vector<Point2f> vector是一个存储二维点坐标的容器,其中每个元素都是一个Point2f类型的对象.在OpenCV中,Point2f表示一个由两个单精度浮点数构成的二 ...

  10. 【JSOI2008】最大值

    [JSOI2008]最大值 线段树裸题!动态RMQ. 这道题的操作是直接在序列末尾添加数值,所以连\(push_{down}\),以及建树什么的都不用了.. 这真是写过的最简短的一道\(seg_{tr ...