• uva1451 Average 单调栈求凸包


    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1<<29;
    
    int n,L;
    ll a[maxn],s[maxn];
    struct Point
    {
        ll x,y;
        friend Point operator-(Point A,Point B)
        {
            return {A.x-B.x,A.y-B.y};
        }
        friend ll operator*(Point A,Point B)
        {
            return 1LL*A.x*B.y-1LL*A.y*B.x;
        }
        void debug()
        {
            printf("%lld %lld
    ",x,y);
        }
    };Point p[maxn],stk[maxn];int tp;
    Point ans,Max;
    
    int main()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        int T;cin>>T;
        while(T--){
            scanf("%d%d",&n,&L);
            REP(i,1,n) scanf("%1d",&a[i]);
            s[0]=0;REP(i,1,n) s[i]=s[i-1]+a[i];
            REP(i,0,n) p[i]={i,s[i]};
            //REP(i,0,n) p[i].debug();cout<<endl;
            tp=0;
            Max=(Point){1,0};ans=(Point){1,L};
            int pre=1;
            REP(i,L,n){
                while(tp>1&&(stk[tp]-stk[tp-1])*(p[i-L]-stk[tp])<0) tp--;
                //cout<<"tp:";stk[tp].debug();
                //cout<<"p[i-L]:";p[i-L].debug();
                //cout<<(stk[tp]-stk[tp-1])*(p[i-L]-stk[tp])<<endl;
                stk[++tp]=p[i-L];
                if(pre>tp) pre=tp;
                int j=pre;
                Point tmp={1,0},res={1,L};
                while(j<=tp){
                    if(tmp*(p[i]-stk[j])>0){
                        tmp=p[i]-stk[j];
                        res=(Point){stk[j].x+1,i};
                        pre=j;
                    }
                    else if(tmp*(p[i]-stk[j])==0){
                        if(i-(stk[j].x+1)<res.y-res.x){
                            tmp=p[i]-stk[j];
                            res=(Point){stk[j].x+1,i};
                            pre=j;
                        }
                        else if(i-(stk[j].x+1)==res.y-res.x){
                            if(stk[j].x+1<res.x){
                                tmp=p[i]-stk[j];
                                res=(Point){stk[j].x+1,i};
                                pre=j;
                            }
                        }
                    }
                    else break;
                    j++;
                }
                if(Max*tmp>0) Max=tmp,ans=res;
                //puts("stk:");REP(i,1,tp) stk[i].debug();
            }
            printf("%lld %lld
    ",ans.x,ans.y);
            //cout<<Max.y<<"/"<<Max.x<<endl;
        }
        return 0;
    }
    
    /**
    直接搞段平均值是很难的,但是平均值可以转化为段和,再转化为前缀和,
    再由构造(i,s[i])的图像通过斜率观察平均值,然后用单调栈维护单调性求个上(下)凸包就可以了。
    本来以为算法出错了,对拍了半天原来是题目看错了。。。fuck。。
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    Roslyn 编译器和RyuJIT 编译器
    go语言---defer
    go语言---for
    go语言--time.After
    go语言---for range
    用gulp打包带参数资源做法与asp.net/java项目结合的自动构建方案探讨
    JQuery判断元素是否存在
    gulp实现打包js/css/img/html文件,并对js/css/img文件加上版本号
    gulp同步执行任务
    gulp-rev同时将js和css文件写在一个rev-manifest.json文件里面的方式探讨
  • 原文地址:https://www.cnblogs.com/--560/p/5041264.html
Copyright © 2020-2023  润新知