• 【NOIP2012】旅行计划


    题解

    双向链表加倍增。。。

    正写着不一定能写对2333

    终于写对了。。。

    然而我的双向链表和别人的都不一样。。。

    瑟瑟发抖。。。

    代码

    //by 减维
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<map>
    #include<algorithm>
    #define ll long long
    #define inf (9223372036854775807LL)
    using namespace std;
    
    struct biao{
        int i,to,fr;
        ll v;
    }e[100005];
    
    int n,m,hest,ys[100005],zj[100005],cj[100005],f[100005][33];
    ll x,her,a[100005][33],b[100005][33],h[100005];
    
    bool cmp(const biao&x,const biao&y){return x.v>y.v;}
    bool cm2(const biao&x,const biao&y){return x.i<y.i;}
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%lld",&e[i].v),e[i].i=i,h[i]=e[i].v;
            if(h[i]>her) her=h[i],hest=i;
        }
        sort(e+1,e+n+1,cmp);
        for(int i=1;i<=n;++i)
            e[i].fr=e[i-1].i,e[i].to=e[i+1].i;
        sort(e+1,e+n+1,cm2);
        for(int i=1;i<=n;++i)
        {
            ll m1=inf,m2=inf,hh[5];int pos[5],a1,a2;
            
            hh[1]=abs(h[i]-h[e[i].fr]);                    pos[1]=e[i].fr;
            hh[2]=abs(h[i]-h[e[e[i].fr].fr]);              pos[2]=e[e[i].fr].fr;
            hh[3]=abs(h[i]-h[e[i].to]);                    pos[3]=e[i].to;
            hh[4]=abs(h[i]-h[e[e[i].to].to]);           pos[4]=e[e[i].to].to;
            
            if(e[i].fr==0)hh[1]=inf;
            if(e[e[i].fr].fr==0)hh[2]=inf;
            if(e[i].to==0)hh[3]=inf;
            if(e[e[i].to].to==0)hh[4]=inf;
            
            for(int j=1;j<=4;++j)
                if(m1>hh[j]||(m1==hh[j]&&h[a1]>h[pos[j]]))m2=m1,a2=a1,m1=hh[j],a1=pos[j];
            else
                if(m2>hh[j]||(m2==hh[j]&&h[a2]>h[pos[j]]))m2=hh[j],a2=pos[j];
            
            if(m1!=inf)zj[i]=a1;
            if(m2!=inf)cj[i]=a2;
            if(e[i].fr!=0)e[e[i].fr].to=e[i].to;
            if(e[i].to!=0)e[e[i].to].fr=e[i].fr;
            
        }
        for(int i=1;i<=n;++i)
        {
            f[i][0]=zj[cj[i]];
            if(i<=n-2)
                a[i][0]=abs(h[i]-h[cj[i]]);
            if(i<=n-1)
                b[i][0]=abs(h[cj[i]]-h[zj[cj[i]]]);
        }
        for(int i=1;i<=22;++i)
            for(int j=1;j<=n;++j)
            {
                f[j][i]=f[f[j][i-1]][i-1];
                a[j][i]=a[j][i-1]+a[f[j][i-1]][i-1];
                b[j][i]=b[j][i-1]+b[f[j][i-1]][i-1];
            }
        
        scanf("%lld",&x);
        int ans=1;
        double m1=inf;
        ll mh=-1;
        for(int i=1;i<=n;++i)
        {
            int pos=i;
            ll l=x,disa=0,disb=0;
            for(int j=22;j>=0;--j)
            {
                if(f[pos][j]!=0&&a[pos][j]+b[pos][j]<=l)
                {
                    disa+=a[pos][j];
                    disb+=b[pos][j];
                    l-=a[pos][j]+b[pos][j];
                    pos=f[pos][j];
                }
            }
            if(a[pos][0]<=l){
                disa+=a[pos][0];
                l-=a[pos][0];
            }
            double c=inf;
            if(disb==0) c=inf;
            else c=disa*1.0/disb;
            if(c<m1||(c==m1&&h[i]>mh))
            {
                m1=c;
                mh=h[i];
                ans=i;
            }
        }
        if(m1!=inf)printf("%d
    ",ans);
        else printf("%d
    ",hest);
        scanf("%d",&m);
        for(int i=1;i<=m;++i)
        {
            int s;
            scanf("%d%lld",&s,&x);
            int pos=s;
            ll l=x,disa=0,disb=0;
            for(int j=22;j>=0;--j)
            {
                if(f[pos][j]!=0&&a[pos][j]+b[pos][j]<=l)
                {
                    disa+=a[pos][j];
                    disb+=b[pos][j];
                    l-=a[pos][j]+b[pos][j];
                    pos=f[pos][j];
                }
            }
            if(a[pos][0]<=l){
                disa+=a[pos][0];
                l-=a[pos][0];
            }
            printf("%lld %lld
    ",disa,disb);
        }
    }
  • 相关阅读:
    C89:论内存泄漏
    C++03:模板
    C++的STL(标准模板库)系列:容器——string容器
    C++03:论类的友元函数和内联函数
    C++03:论类的运算符重载
    Windows开发:网络编程基础
    Windows开发:论文件和权限
    C89:头文件
    C89:论符号
    纪录片(深度好片)
  • 原文地址:https://www.cnblogs.com/rir1715/p/7695611.html
Copyright © 2020-2023  润新知