题目链接:Maximum And Queries (easy version)
首先转化成二进制去思考,本题就是明显的贪心题,要使最多在k步操作下使得所有数的与最大,那么我们可以从高位往低位枚举,如果高位可以变成1,那么我们把所有的数该位都变成1,那么答案的该位也变成了1 。
同时我们由于是从高位往低位枚举,那么之前的高位对低位没有影响,因此可以把该位之前的所有位数都变成0方便运算,假设该位为0,那么步数就是2^i - a[j],然后a[j]就变成2^i。
代码附上:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6+5;
int n,q;
int a[N];
int b[N];
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)b[i]=a[i];//为了复原
while(q--){
int k;cin>>k;
int ans=0;
for(int i=1;i<=n;i++)a[i]=b[i];
for(int i=62;i>=0;i--){//高位往低位枚举
bool flag=false;
int sum=0;
for(int j=1;j<=n;j++){
if(a[j]&(1LL<<i))continue;//当前位数为1
sum+=(1LL<<i)-a[j];
if(sum>k)break;//防止爆int
}
if(sum<=k){//如果可以将所有数的第i位都变成1
flag=true;
ans+=(1LL<<i);
k-=sum;
}
for(int j=1;j<=n;j++){
if(flag&&(a[j]&(1LL<<i))==0){//将a[j]变成2^i
a[j]=(1LL<<i);
}
if(a[j]&(1LL<<i)){//对后面没有影响,方便计算
a[j]-=(1LL<<i);
}
}
}
cout<<ans<<"\n";
}
return 0;
}