Title link: https://ac.nowcoder.com/acm/contest/8563/C
answer:
First of all we need to know z^k=z+k-2*(z&k);
The cost of only one operation: (r-l+1)*((z^k)+kz)=2*(r-l+1)(kz&k).
For kz&k, we have to make it as small as possible , Then if z is a larger subset of k. Then we enumerate and save the subset of k, and sort them.
Then we enumerate i=0->n until the sum of the first i numbers in the arithmetic sequence is greater than y
For each i, we calculate the sum of the previous i numbers s[i], in order to satisfy that the sum of the entire sequence is less than y, for each remaining number, it must be less than or equal to (ys[i])/(ni) , Ie [0,(ys[i])/(ni)]
Then we need to find the largest subset of k in this interval, and then we can perform a binary search on the previously saved array of k subsets, and then calculate the answer at this time.
See the code for details:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
typedef long long ll;
ll n,a,d,k,y;
ll s[maxn];
ll si[maxn];
int cnt;
signed main() {
cin>>n>>a>>d>>k>>y;
ll x=a;
ll sub=k;
ll ans=1e18;
//枚举k的子集
do{
si[++cnt]=sub;
sub=(sub-1)&k;
} while(sub!=k);
sort(si+1,si+cnt+1);
//i=0的情况
ll minx=(y-s[0])/(n-0);
int p=upper_bound(si+1,si+1+cnt,minx)-si-1;
ans=ans=min(ans,1LL*2*(n-0)*(k-si[p]));
//1-n的情况
for(int i=1;i<=n;++i) {
if(i==1) s[i]=x;
else x+=d,s[i]=s[i-1]+x;
if(s[i]>y) break;
ll minx=(y-s[i])/(n-i);
int p=upper_bound(si+1,si+1+cnt,minx)-si-1;
ans=ans=min(ans,1LL*2*(n-i)*(k-si[p]));
}
cout<<ans<<endl;
}