CF2147E Maximum OR Popcount题解
CF2147E Maximum OR Popcount
安利一下我的博客。
思路
考虑求出最终或和中有
接着考虑第
代码
实现方法很多我的应该是最劣的。时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct js
{
int w,id;
};
bool operator <(js x,js y)
{
return x.w<y.w;
}
int t,n,q,a[N],ans[35];
vector<js> s[35];
int cnt1[35],cnt2[35];
bool bj[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--)
{
cin>>n>>q;
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
for(int i=1;i<=n;i++)
{
cin>>a[i];
for(int j=0;j<=30;j++)
{
s[j].push_back({(1<<j)-a[i]%(1<<(j+1)),i});
cnt1[j]+=((1<<j)&a[i])>0;
}
}
int cnt=0;
for(int j=0;j<=30;j++)
{
s[j].push_back({1<<j,0});
sort(s[j].begin(),s[j].end());
if(cnt1[j]) cnt++;
}
int now=0;
for(int i=0;i<=31;i++)
{
memset(bj,0,sizeof(bj));
for(int j=0;j<=30;j++) cnt2[j]=cnt1[j];
if(i<=cnt) ans[i]=0;
else
{
while(now<=30&&cnt1[now]) now++;
int res=0;
for(int j=now;j>=0;j--)
{
if(!cnt2[j])
for(int k=0;k<s[j].size();k++)
if(!s[j][k].id||!bj[s[j][k].id])
{
bj[s[j][k].id]=1,res+=s[j][k].w;
for(int p=j-1;p>=0;p--)
cnt2[p]-=(a[s[j][k].id]&(1<<p))>0;
break;
}
}
now++,ans[i]=res;
}
}
while(q--)
{
int x;
cin>>x;
int res=0;
for(int i=0;i<=31;i++)
if(ans[i]<=x) res=i;
else break;
cout<<res<<"\n";
}
for(int i=0;i<=30;i++) s[i].clear();
}
return 0;
}