首页 > 其他分享 >位位运算

位位运算

时间:2022-10-09 19:36:01浏览次数:72  
标签:ch return 运算 位位 int while ans

位位运算

思路

观察一下题中所说的“将其中一个数变为 \(a\) \(and\) \(b\),另一个变成 \(a\) \(or\) \(b\)”,这个操作事实上是将\(a\)和\(b\)对应二进制位不同的\(0\)和\(1\)交换。如\(10\)和\(12\),对应二进制分别为\(1010\)和\(1100\),\(a|b=1110\),\(a\) & \(b=1000\),实质上是把\(a\)和\(b\)中对应位上的\(1\)挪到一边。

题目要求使所有数的平方和最大,显然在\(a、b\)在操作前后它们的和不变,要使平方和最大,就要使差最大。所以我们要尽可能把\(1\)集中到几个数上。做法是先把数排个序,从高位往低位扫,每次找到从左往右第一个第\(i\)位为\(0\)的数和从右往左第一个第\(i\)位为\(1\)的数,把它们的第\(i\)位交换即可。对每一位都进行这样的操作,最终得到的数组就是构成最佳答案的数组。

可能会有人对操作中的“交换第\(i\)位”有疑惑:我们对两个数操作的时候是把所有能移动的位都交换了,但在这里只移了一位,这样不会出问题吗?其实我们在这里虽然移了\(1\)位,但在之后的操作中一定会把剩下的位移动,因为我们是按位操作的。

代码

#include<bits/stdc++.h>
#define MAXN 100010
#define int long long
using namespace std;
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
inline void write(int x)
{
	if(x<0){putchar('-');x=-x;}
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
bool cmp(int a,int b)
{
    return a>b;
}
int n,num[MAXN],vis[MAXN],ans=0;
int wei(int x)
{
    int ans=0;
    while(x)
    {
        x>>=1;
        ans++;
    }
    return ans;
}
string to_b(int x)
{
    string ans;
    while(x)
    {
        ans+=(x%2+'0');
        x>>=1;
    }
    if(ans.length()==0)ans+='0';
    reverse(ans.begin(),ans.end());
    return ans;
}
signed main()
{
    n=read();
    for(int i=1;i<=n;i++)
        num[i]=read();
    sort(num+1,num+n+1,cmp);
    int len=wei(num[1]);
    for(int i=len-1;i>=0;i--)
    {
        int l=1,r=n;
        while(1)
        {
            while(l<r&&(num[l]&(1<<i)))l++;
            while(l<r&&(!(num[r]&(1<<i))))r--;
            if(l>=r)break;
            num[l]|=(1<<i);
            num[r]-=(1<<i);
        }
    }
    for(int i=1;i<=n;i++)
        ans+=num[i]*num[i];
    write(ans);
    return 0;
}

标签:ch,return,运算,位位,int,while,ans
From: https://www.cnblogs.com/huled/p/16773229.html

相关文章

  • 位位运算 方法记录
    题解位运算简单理解:and(&):有假则假;or(|):有真则真;不妨从输入样例入手,看看能有什么发现。举几个例子:1(001)&2(010)==3(011)1(001)|2(010)==0(000)2(010......
  • python调用c++的方法,加速运算
    cpp源代码#include"iostream"usingnamespacestd;classCalc{public:intadd(inta,intb);};intCalc::add(inta,intb){cout<<"收到参数为a,b:"<<a<......
  • 位位运算 方法记录
    题解我们首先来分析小朋友的三个指标:手里的数,特征值,分数。手里的数:即我们输入的长度为\(n\)的序列;特征值:从第一个小朋友到当前小朋友的手上的数的最大子段和;分数......
  • java---了解以下运算符
    了解即可1&2用于条件判断,&条件1和2都执行1&&2,条件1判断错误的情况下,条件2不执行&当运算符的化,例如4&7,两者上下对比都是1则为1,反之为0,结果就是二进制100也就是......
  • 快速幂,位运算,pow()函数
    位运算:位运算可以用来查找01二进制串中1或0的个数,同时也可以实现幂的计算,但是只能是以2为底的幂运算统计字符串中1的个数#include<bits/stdc++.h>usingnamespacestd;......
  • 布尔类型、比较运算符
    布尔类型True表示真(是、肯定)False表示假(否、否定)变量名称=布尔类型字面量比较运算符代码案例#定义变量存储布尔类型的数据bool_1=Truebool_2......
  • 一篇文章介绍 符号运算的妙用
    以后把看到的觉得有用的符号运算记录下来。符号运算效率会更高一点,虽然甚微,但是还是有的。我记录的都是实用的,要是用上自己都看不懂,就有点搬石头砸自己的脚了。 ## 判断......
  • 运算符
    运算符(自增自减)Java语言支持的运算符算数运算符:+-*/%++--赋值运算符=关系运算符><<=>===!=instanceof逻辑运算符&&||!位运算符......
  • 第二章:数据类型、运算符和表达式
    目录​​一、在屏幕上输出英文短句“Programmingisfun.”。​​​​ 二、输入半径,分别计算球体积和球表面积。​​​​ 三、转义字符使用示例。​​​​ 四:利用符号常......
  • 20内加法运算式
    SubnewPages()Application.DisplayAlerts=FalseDimWbAsWorkbookDimNewShtAsWorksheetDimiSetWb=Application.ThisWorkbookFo......