Loading

CF1903D1 Maximum And Queries (easy version) 题解

Problem

Solution

考虑按位贪心。

简单计算发现 \(2^{60}>10^{18}\),所以我们从 \(60\) 倒着枚举。

对于每一位,我们发现要使最终答案的当前位为 \(1\),则一定要保证所有数的当前位全部为 \(1\),所以我们可以考虑要使所有数的当前位为 \(1\) 需要进行的操作数,再与 \(k\) 判断大小,若大则 \(k\) 减掉继续,若小则忽略当前位,最终计算最终结果(我们不需要全部使用 \(k\) 次操作)。

注意多定义几个数组临时存放数据。

Code

#include<bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define FOR(i,a,b) for(int i=(a);i>=(b);i--)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define int long long

const int N=1e5+4;
int n,a[N],b[N],c[N];
void solve()
{
	int k;cin>>k;
	For(i,1,n)a[i]=b[i];
	FOR(w,60,0)
	{
		For(i,1,n)c[i]=a[i];
		int cnt=0;
		For(i,1,n)
		{
			if((a[i]>>w)%2==0)
			{
				int p=((a[i]>>w)+1)<<w;
				cnt+=p-a[i];
				a[i]=p;
			}
			if(cnt>k)break;
		}
		if(cnt<=k)k-=cnt;
		else For(i,1,n)a[i]=c[i];
	}
	int ans=a[1];
	For(i,2,n)ans&=a[i];
	cout<<ans<<"\n";
}
signed main()
{
	IOS;
	int q;cin>>n>>q;
	For(i,1,n)cin>>a[i],b[i]=c[i]=a[i];
	while(q--)solve();

	return 0;
}
posted @ 2024-08-05 20:22  ๑҉v  阅读(17)  评论(0)    收藏  举报