In this HackerEarth Minimum Flip problem solution, You are given an array of N numbers.
An operation on the array is defined as :
- Select a non-empty subarray of the array and a number j. Now flip the j-th bit of all the elements of this subarray.
- Output the minimum sum of the elements of the given array that can be obtained after doing the above operation at most K times.
HackerEarth Minimum Flip problem solution.
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define sc(n) scanf("%d",&n)
#define scl(n) scanf("%lld",&n)
#define pr(n) printf("%d",n)
#define prl(n) printf("%lld",n)
#define nl printf("n")
#define fr(i,n) for(i=0;i<n;i++)
#define rep(i,st,en) for(i=st;i<=en;i++)
#define repv(i,en,st) for(i=en;i>=st;i--)
#define fout cout<<fixed<<setprecision(7)
#define bi(n) __builtin_popcount(n)
#define bil(n) __builtin_popcountll(n)
typedef long long ll;
typedef pair<int,int> pii;
const int N = 100010;
ll mod = 1e9+7;
ll fmod(ll b,ll exp){
ll res =1;
while(exp){if(exp&1ll)res=(res*b)%mod;
b =(b*b)%mod;exp/=2ll;
}
return res;
}
int A[N],B[N];
ll C[20*N];
struct node{
int mxbest,mxlft,mxrt;
int mnbest,mnlft,mnrt;
int sm;
node(){};
node(int val){
sm = val;mnlft = val;mxlft = val;
mxrt = val; mnrt = val;mxbest = val;
mnbest = val;
}
void flip(){
sm = -sm;
swap(mxbest,mnbest);
swap(mnlft,mxlft);swap(mxrt,mnrt);
mxbest = -mxbest;mxlft = -mxlft;
mxrt = -mxrt;mnbest = -mnbest;
mnlft = -mnlft; mnrt = -mnrt;
}
};
node tr[4*N];
int lazy[4*N];
node merge(node &a,node &b)
{
node p;
p.mxbest = max(a.mxbest,max(b.mxbest,a.mxrt+b.mxlft));
p.mxlft = max(a.mxlft,a.sm+b.mxlft);
p.mxrt = max(b.mxrt, b.sm+a.mxrt);
p.mnlft = min(a.mnlft,a.sm+b.mnlft);
p.mnrt = min(b.mnrt,b.sm+a.mnrt);
p.mnbest = min(a.mnbest,min(b.mnbest,a.mnrt+b.mnlft));
p.sm = a.sm + b.sm ;
return p;
}
void build(int i,int st,int en){
lazy[i]=0;
if(st == en){
tr[i] = node(B[st]);
return;
}
int mid = (st+en)>>1;
build(i+i,st,mid);build(i+i+1,mid+1,en);
tr[i]= merge(tr[i+i],tr[i+i+1]);
}
inline void prop(int i,int st,int en){
if(lazy[i] && st!=en){
tr[i+i].flip();
lazy[i+i]^=1;
tr[i+i+1].flip();
lazy[i+i+1]^=1;
}
lazy[i]=0;
}
void upd(int i,int st,int en,int l,int r){
if(st >r || l>en || st>en)return;
if(st>=l && en<=r){
tr[i].flip();
lazy[i]^=1;
return;
}
if(lazy[i])prop(i,st,en);
int mid = (st+en)>>1;
if(l<= mid )upd(i+i,st,mid,l,r);
if(r>mid)upd(i+i+1,mid+1,en,l,r);
tr[i]= merge(tr[i+i],tr[i+i+1]);
}
int getLft(int i,int st,int en,int val){
if(tr[i].sm == val)return st;
int mid = (st+en)>>1;
if(lazy[i])prop(i,st,en);
if(tr[i+i+1].mxrt == val)return getLft(i+i+1,mid+1,en,val);
return getLft(i+i,st,mid,val-tr[i+i+1].sm);
}
int getRt(int i,int st,int en,int val){
if(tr[i].sm == val)return en;
int mid = (st+en)>>1;
if(lazy[i])prop(i,st,en);
if(tr[i+i].mxlft == val)return getRt(i+i,st,mid,val);
return getRt(i+i+1,mid+1,en,val-tr[i+i].sm);
}
pair<int,int> getAnswer(int i,int st,int en,int val){
if(tr[i].sm == val)return mp(st,en);
if(lazy[i])prop(i,st,en);
int mid = (st+en)>>1;
if(tr[i+i].mxbest == val)return getAnswer(i+i,st,mid,val);
if(tr[i+i+1].mxbest == val)return getAnswer(i+i+1,mid+1,en,val);
int l1 = getLft(i+i,st,mid,val-tr[i+i+1].mxlft);
int r1 = getRt(i+i+1,mid+1,en,val-tr[i+i].mxrt);
return mp(l1,r1);
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
//ios_base::sync_with_stdio(false);cin.tie(NULL);
int n,m,i,j,k,x,q;
int t=1;
cin>>n>>k;
ll ans = 0;
int len = 0;
rep(i,1,n){
cin>>A[i];
ans += A[i];
}
for(int bit=19;bit>=0;bit--){
rep(i,1,n)if((1<<bit)&A[i])B[i]=1;
else B[i]=-1;
build(1,1,n);
while(tr[1].mxbest>0)
{
int cur = tr[1].mxbest;
pair<int,int> ind = getAnswer(1,1,n,cur);
upd(1,1,n,ind.f,ind.s);
C[++len] = (1ll<<bit)*1ll*cur;
}
}
sort(C+1,C+len+1);
reverse(C+1,C+len+1);
rep(i,1,min(k,len)){
// cout<<C[i]<<"n";
ans-=C[i];
}
cout<<ans<<"n";
return 0;
}