230 words
1 minute
Normal_Algorithms
二分
一些奇奇怪怪的二分
CF2120 有个显然的贪心是将最大的末尾移到最小末尾去 不难(挺难)发现,最后的的序列类似,发现这样可能最后与总数不相符,我们需要微调一下。 发现上面总数单增,记总数为,发现单增,我们可以二分求出满足 然后,多出来的分配给(因为我们优先放到小的后面),还不够就分配给 因为懒,直接沾自己代码了(有的时候,看代码更易懂)
ll S(int l){ ll r=1ll*(l+k); ll sum=0; for (int i=1;i<=n;i++){ if (l<=a[i]&&a[i]<=r)b[i]=a[i],sum+=b[i]; else if (a[i]<l)b[i]=l,sum+=b[i]; else b[i]=r,sum+=b[i]; } return sum;}void init(){ scanf("%d%d",&n,&k);s=0; for (int i=1;i<=n;i++)scanf("%d",a+i),s+=1ll*a[i]; std::sort(a+1,a+n+1);}void solve(){ int l=a[1],r=a[n]-k; while (r-l>1){ int mid=(l+r)>>1; if (S(mid)<=s)l=mid; else r=mid-1; } while (S(l)<=s)l++;l--; r=l+k; ll sum=S(l); for (int i=1;sum<s&&i<=n;i++) if (a[i]<=l)b[i]++,sum++; for (int i=1;sum<s&&i<=n;i++) if (a[i]>r)b[i]++,sum++; ll ans=0; for (int i=1;i<=n;i++){ if (a[i]<b[i])ans+=1ll*(b[i]-a[i])*k; ans+=1ll*b[i]*(b[i]+1)/2; } printf("%lld\n",ans);}贪心
两些奇奇怪怪的贪心
Normal_Algorithms
https://fuwari.vercel.app/posts/normal_algorithms/