Niuke Challenge 45——C Friend Problem Solution

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;
}

 

Guess you like

Origin blog.csdn.net/qq_44132777/article/details/109684940