UVALive 4726Average 单调队列+斜率优化

来源:互联网 发布:java 线程 wait 编辑:程序博客网 时间:2024/05/22 09:41

具体的解法请参看《浅谈数形结合思想在信息学竞赛中的应用》。本题中使用叉积可以避免所有浮点运算。

#include<cstdio>#define maxn 100009#define LL long longusing namespace std;LL Cross(LL xa,LL ya,LL xb,LL yb)//向量(xa,xb)和向量(ya,yb)求叉积,通过叉积正负判断斜率关系{    return xa*yb-ya*xb;}char s[maxn];int q[maxn*2];int sum[maxn];int main(){    int tt,n,l;    scanf("%d",&tt);    while(tt--)    {        scanf("%d%d%s",&n,&l,s+1);        for(int i=1;i<=n;i++)            if(s[i]=='1')   sum[i]=sum[i-1]+1;            else sum[i]=sum[i-1];        int head=0,rear=-1;        int ansl=0,ansr=l;        for(int i=l;i<=n;i++)        {            while(rear-head>=1&&Cross(q[rear]-q[rear-1],sum[q[rear]]-sum[q[rear-1]],i-l-q[rear],sum[i-l]-sum[q[rear]])<=0)rear--;            q[++rear]=i-l;            while(rear-head>=1&&Cross(i-q[head],sum[i]-sum[q[head]],i-q[head+1],sum[i]-sum[q[head+1]])>=0)head++;            int it=q[head];            if(Cross(ansr-ansl,sum[ansr]-sum[ansl],i-it,sum[i]-sum[it])>0)            {                ansl=it,ansr=i;            }            else if(Cross(ansr-ansl,sum[ansr]-sum[ansl],i-it,sum[i]-sum[it])==0)            {                if(i-it<ansr-ansl)                {                    ansr=i;                    ansl=it;                }            }        }        printf("%d %d\n",ansl+1,ansr);    }}



0 0