CodeForces Round #143(231C) - To Add or Not to Add

来源:互联网 发布:数控镗床圆弧编程举例 编辑:程序博客网 时间:2024/06/05 10:52

     基本思路是每次确定上界..二分找下界的最小合法值....

     那么关键就在于如何快速得出两个位置之间需要做的操作次数...如样例中的数据

              a=6 3 4 0 2

     先排序为:

              a=0 2 3 4 6

     预处理..算出要使小于a[i]的数要做几次操作才能全等于a[i]...那么对应的值为

              s=0 2 4 7 15

     如果要问3~6要全等于a[6]所需的操作次数..及3 4 6全等于6...先算出0 2 6的次数sum..然后用s[6]-sum..则是所需...而0 2 6的计算为 2*(a[6]-a[2])+s[2]....所以可以算出3 4 6要全为6...操作次数为s[6]-sum=15-10=5


Program:

#include<iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<math.h>#include<map>#include<queue>#include<stack>#include<set>#define ll long long#define oo 2000000000#define pi acos(-1)  using namespace std;    ll n,k,m,a[100005],s[100005];int main(){     scanf("%I64d%I64d",&n,&k);    ll i,j,sum,ans1,ans2;    for (i=1;i<=n;i++) scanf("%I64d",&a[i]);     sort(a+1,a+1+n);      s[0]=0;    for (i=2;i<=n;i++) s[i]=s[i-1]+(a[i]-a[i-1])*(i-1);     ans1=0;    for (i=1;i<=n;i++)    {           int l,r,mid;           l=0;  r=i+1;           while (r-l>1)           {                 mid=(l+r)/2;                  sum=s[i]-(s[mid-1]+(mid-1)*(a[i]-a[mid-1]));                 if (sum>k) l=mid;                    else r=mid;           }           if (i-r+1>ans1)           {                 ans1=i-r+1;                 ans2=a[i];           }    }    printf("%I64d %I64d\n",ans1,ans2);    return 0;}


原创粉丝点击