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