HDU 5192 [迷之WA!]

来源:互联网 发布:淘宝星级 编辑:程序博客网 时间:2024/04/19 03:14

狂WA不止!!!到底错哪里了!!!!!!!!

*******************************************************************

和标称对拍的数据都对了。。。。真是不知道能错哪里。。。。。

不过对拍的时候发现一种情况没有考虑到,就是可能从一堆中把W堆都分出去。然后终于发现错哪里之后我就改去了。然后满怀欣喜的又WA了一发。。。。。。

#include <stdio.h>#include <iostream>#include <string.h>using namespace std;#define maxn 9999999999999999#define ll long longll mx;ll tree[50100],cnt[50100],ans;ll n,w,h,mh,num,b[50100*3];ll sum[50100*3];ll lowbit(ll x){return x&(-x);}void update(ll pos,ll x,ll flag){    while(pos<=mx)    {        tree[pos]+=x;        cnt[pos]+=flag;        pos+=lowbit(pos);    }}ll query(ll end){    ll ret=0;    while(end>0)    {        ret+=tree[end];        num+=cnt[end];        end-=lowbit(end);    }    return ret;}ll judge(ll j,ll k,ll h,ll res){    ll tmp=j-k;    if(tmp>=0)    {        if(j<ans) ans=j,mh=h;        else if(j==ans&&h>mh) mh=h;        ll p=tmp/w,q=tmp%w;        ll r=w-q;        if(r>q) return p;        else        {            if(res>=r) return p+1;            else return p;        }    }    else    {        if(res>=-tmp)        {            if(k<ans) ans=k,mh=h;            else if(k==ans&&h>mh) mh=h;            return 0;        }    }    return 0;}void work(){    ll i;    ll j,k;    j=0,k=w*h;    for(i=1;i<=n+w;i++)   //这里要有等号,不然会漏掉一种情况    {        if(b[i+w-1]!=0)update(b[i+w-1],b[i+w-1],1);        if(b[i-1]!=0) update(b[i-1],-b[i-1],-1);        ll tmp=b[i-1]-h;        if(tmp>0) j-=tmp;        else k+=tmp;        tmp=b[i+w-1]-h;        if(tmp>0) j+=tmp;        else k-=tmp;        ll msum=sum[i+w-1]-sum[i-1];                ll res=sum[n+w-1]-msum;        ll flag=judge(j,k,h,res);                if(flag)        {            ll jj,kk;            num=0;            if(i<w) num+=(w+1-i);            else if(i+w-1>=n+w) num+=i-n;            ll th=h+flag;            ll sum1=0,sum2=0;            sum2=query(th);            sum1=msum-sum2;            jj=sum1-th*(w-num);            kk=th*(num)-sum2;            judge(jj,kk,th,res);        }    }}void init(){    ll i;    for(i=0;i<=mx;i++) tree[i]=0,cnt[i]=0;}int main(){    while(scanf("%lld%lld%lld",&n,&w,&h)!=EOF)    {        ll i;        ans=maxn;        mh=h;        mx=0;        for(i=0;i<w;i++) b[i]=0,sum[i]=0;        for(i=w;i<n+w;i++)        {            scanf("%lld",&b[i]);            sum[i]=sum[i-1]+b[i];            mx=max(mx,b[i]);        }        for(i=n+w;i<n+w+w;i++) b[i]=0,sum[i]=sum[i-1];        if(sum[n+w-1]<w*h) {printf("-1\n");continue;}        init();        work();        if(ans==maxn) printf("-1\n");        else printf("%lld %lld\n",mh,ans);    }    return 0;}


0 0