CF1903D2 Maximum And Queries (hard version)
MaxBlazeResFire · · 题解
这个题很会创人啊。经典
首先一眼贪心,设当前正在确定答案第
瓶颈在于求出每次贪心的
复杂度
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 1200005
int n,q,a[MAXN],f[20][MAXN],g[20][MAXN];
signed main(){
scanf("%lld%lld",&n,&q); int S = 0;
for( int i = 1 ; i <= n ; i ++ ) scanf("%lld",&a[i]),S += ( 1 << 20 ) - a[i];
for( int p = 19 ; p >= 0 ; p -- ){
for( int j = 1 ; j <= n ; j ++ ) if( !( a[j] >> p & 1 ) ) f[p][a[j]] ++,g[p][a[j]] += a[j] & ( ( 1 << p ) - 1 );
for( int k = 0 ; k <= 19 ; k ++ )
for( int i = MAXN - 5 ; i >= 0 ; i -- )
if( i & ( 1 << k ) ) f[p][i - ( 1 << k )] += f[p][i],g[p][i - ( 1 << k )] += g[p][i];
}
for( int i = 1 ; i <= q ; i ++ ){
int k; scanf("%lld",&k);
if( k >= S ){ printf("%lld\n",( 1 << 20 ) + ( k - S ) / n ); continue; }
int res = 0,cat = 0;
for( int p = 19 ; p >= 0 ; p -- ){
int cost = cat * ( 1 << p ) + f[p][res] * ( 1 << p ) - g[p][res];
if( k >= cost ) cat += f[p][res],res += 1 << p,k -= cost;
}
printf("%lld\n",res);
}
return 0;
}