0
点赞
收藏
分享

微信扫一扫

51nod 2527 Or 和 Sum 和2526 最大异或和 二进制拆分


2526 最大异或和

  1. 2.0 秒
  2.  
  3. 262,144.0 KB
  4.  
  5. 20 分
  6.  
  7. ​​3级题​​

给定nn个数x1…xnx1…xn,请你选择n个数p1…pnp1…pn,使得p1<=x1,p2<=x2......p1<=x1,p2<=x2......,并且p1xorp2…pnp1xorp2…pn的值尽量大。问这个最大的异或和是多少。

n≤100,0≤xi≤109n≤100,0≤xi≤109

 收起

输入


第一行一个正整数 n 。 第二行 n 个非负整数表示 x[1...n] 。


输出


一行一个数表示答案。


输入样例


3 2 2 2


输出样例


3


分析:

这个题和下面那个题都是二进制拆分+运算性质。

这一题,我们把所有的二进制都拆开,因为我们可以选在比他小的任意一个数,假如一个数的二进制为1000,则他的最后三位是可以任意构造的,即1000 1001 1010 1011……那我们异或最大肯定是每一位都不相同才是最大的。所以我们用num[i]保存i的dii为1的个数,如果遇到了第一个1,则后面的都可以为1。

比如:

1001000

      0100

         100

ans=1001111

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
LL a[N],power[100];
int num[N];
int n;
void cal(LL x)
{
int j=0;
while(x)
{
if(x%2==1)
num[j]++;
x/=2;
j++;
}
}
int main()
{
scanf("%d",&n);
LL ans=0;

for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
cal(a[i]);
}

for(int i=35; i>=0; i--)
{
if(num[i]==1)
{
ans+=pow(2,i);
}
else if(num[i]>=2)
{
for(int j=i; j>=0; j--)
ans+=pow(2,j);

break;
}
}
printf("%lld\n",ans);

return 0;
}

2527 Or 和 Sum

  1. 2.0 秒
  2.  
  3. 262,144.0 KB
  4.  
  5. 20 分
  6.  
  7. ​​3级题​​

给定两个非负整数 pairOr,pairSumpairOr,pairSum,请你构造两个非负整数 A,BA,B,使得A|B=pairOr,A+B=pairSumA|B=pairOr,A+B=pairSum。

你只需输出是否能构造出满足条件的 A,BA,B 。若可以,输出 PossiblePossible ,否则输出

ImpossibleImpossible 。

0<=pairOr,pairSum<=10180<=pairOr,pairSum<=1018

 收起

输入


一行两个数,分别表示pairOr和pairSum。


输出


一行一个字符串。若可以,输出 Possible ,否则输出 Impossible 。


输入样例


7 11


输出样例


Possible


这题考察了一个进位的东西。

a+b=sum与a|b=or把他们看成二进制位相加,还是很好做的,我们知道|,只有在对应二进制位都为0的时候才能为1,即如果or的二进制位为0,则sum的二进制为0,但有一种特殊的情况,就是进位,比如

1011

1011

or:     1011

sum:10110

所以需要保证or0的前一个位置为1即可。

还有就是sum的二进制位个数要么等于or的二进制位个数,要么等于or的二进制位个数+1

题解:

规律代码

 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
LL n,m;
int num[10][100];
int maxx;
void cal(int i,LL x)
{
int j=0;
while(x)
{
if(x%2==1)
num[i][j]=1;
x/=2;
j++;
}
num[i][99]=j;
maxx=max(j,maxx);
}
int main()
{

scanf("%lld%lld",&n,&m);
if(n>m)
{
printf("Impossible\n");
return 0;
}
maxx=-1e9;
cal(1,n);
cal(2,m);
/*
for(int i=32; i>=0; i--)
{
cout<<num[1][i];
}
cout<<endl;

for(int i=32; i>=0; i--)
{
cout<<num[2][i];
}
cout<<endl;
cout<<num[1][99]<<" "<<num[2][99]<<endl; */
if(num[1][99]>num[2][99]||(num[1][99]<num[2][99]&&num[1][99]!=num[2][99]-1))
{
printf("Impossible\n");
return 0;
}

for(int i=maxx; i>=0; i--)
{

if(num[1][i]==0&&num[2][i]==1)
{
if(i>0&&num[1][i-1]!=1)
{
//cout<<i<<endl;
printf("Impossible\n");
return 0;
}
}
}
printf("Possible\n");


return 0;
}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int main()
{
ll x,y;
cin>>x>>y;
ll c=y-x;
if((c|x)==x)
cout<<"Possible"<<endl;
else
cout<<"Impossible"<<endl;
return 0;
}

 

举报

相关推荐

0 条评论