Niuke Challenge 45 —— C Friend Problema Solución

Enlace de título: https://ac.nowcoder.com/acm/contest/8563/C

responder:

En primer lugar, necesitamos saber z ^ k = z + k-2 * (z & k);

El costo de una sola operación: (r-l + 1) * ((z ^ k) + kz) = 2 * (r-l + 1) (kz & k).
Para kz & k, tenemos que hacerlo lo más pequeño posible , Entonces si z es un subconjunto más grande de k. Luego enumeramos y guardamos el subconjunto de k, y los ordenamos.

Luego enumeramos i = 0-> n hasta que la suma de los primeros i números en la secuencia aritmética sea mayor que y

Para cada i, calculamos la suma de los i números anteriores s [i], con el fin de satisfacer que la suma de toda la secuencia es menor que y, para cada número restante, debe ser menor o igual a (ys [ i]) / (ni), es decir, [0, (ys [i]) / (ni)]

Luego, necesitamos encontrar el subconjunto más grande de k en este intervalo, podemos realizar una búsqueda binaria en la matriz de k subconjuntos guardada previamente y luego calcular la respuesta en este momento.

Consulte el código para obtener más detalles:

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

 

Supongo que te gusta

Origin blog.csdn.net/qq_44132777/article/details/109684940
Recomendado
Clasificación