zoukankan      html  css  js  c++  java
  • 【NOIP2012】开车旅行

    题面

    https://www.luogu.org/problem/P1081

    题解

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<set>
    #include<algorithm>
    #include<vector>
    #include<cstdlib>
    #include<cassert>
    
    using namespace std;
    
    const long long INF=100000000000LL;
    
    struct city{
      int num;
      long long h;
      bool operator < (const city rhs) const {
        return h<rhs.h;
      }
    };
    
    set<city> s;
    vector <int> son[205000];
    int fa[205000],f[205000][20],n,m,p;
    long long h[105000],sum1[205000],sum2[205000],sum0[205000],x0;
    bool vis[205000];
    double val;
    
    long long abq(long long x){
      if (x>=0) return x; else return -x;
    }
    
    bool smaller(int x,city yuan,city now){
      if (abq(now.h-h[x])<abq(yuan.h-h[x])||
        (abq(now.h-h[x])==abq(yuan.h-h[x])&&now.h<yuan.h)) return true; else return false;
    }
    
    double fabs(double x){
      if (x>=0) return x; else return -x;
    }
    long long hei(int x){
      if (x>n) return h[x-n]; else return h[x];
    }
    
    bool dengyu(double x,double y){
      if (fabs(x-y)<=1e-6) return true; else return false;
    }
    
    set<city>::iterator it,pit,ppit,sit,ssit,nul;
    city mym,smym;
    
    void maketree(int x){
      int i,l=son[x].size();
      if (fa[x]!=-1) f[x][0]=fa[x]; else f[x][0]=x;
      for (i=1;i<=19;i++) f[x][i]=f[f[x][i-1]][i-1];
      if (fa[x]!=-1){
        sum0[x]=sum0[fa[x]]+abq(hei(fa[x])-hei(x));
        if (x>n) sum1[x]=sum1[fa[x]]+abq(hei(fa[x])-hei(x)),sum2[x]=sum2[fa[x]];
            else sum2[x]=sum2[fa[x]]+abq(hei(fa[x])-hei(x)),sum1[x]=sum1[fa[x]];
      }
      for (i=0;i<l;i++) maketree(son[x][i]);
    }
    
    int dfs(int x){
      int i;
      long long sum=0;
      for (i=19;i>=0;i--) if (sum0[x]-sum0[f[x][i]]+sum<=x0) {
        sum+=sum0[x]-sum0[f[x][i]];
        x=f[x][i];
      }
      return x;
    }
    
    set<city> empty;
    
    int main(){
      int i,ss;
      city now;
      nul=empty.begin();
      scanf("%d",&n);
      for (i=1;i<=n;i++) scanf("%lld",&h[i]);
      for (i=n;i>=1;i--) {
        now=(city){i,h[i]};
        s.insert(now);
        it=s.lower_bound(now);
        ppit=pit=sit=ssit=it;
        if (pit!=s.begin()) {
          pit--; ppit--;
          if (ppit!=s.begin()) ppit--; else ppit=nul;
        }
        else ppit=pit=nul;
        ++sit; ++ssit;
        if (sit==s.end()) ssit=sit=nul; 
        else {
          ++ssit;
          if (ssit==s.end()) ssit=nul;
        }
        mym=(city){2*n+1,INF};
        smym=(city){2*n+1,INF};
        if (ppit!=nul && smaller(i,mym,*ppit)) smym=mym,mym=*ppit; 
            else if (ppit!=nul && smaller(i,smym,*ppit)) smym=*ppit;
        if (pit!=nul  && smaller(i,mym,*pit)) smym=mym,mym=*pit; 
            else if (pit!=nul && smaller(i,smym,*pit)) smym=*pit;
        if (sit!=nul  && smaller(i,mym,*sit)) smym=mym,mym=*sit; 
            else if (sit!=nul && smaller(i,smym,*sit)) smym=*sit;
        if (ssit!=nul && smaller(i,mym,*ssit)) smym=mym,mym=*ssit; 
            else if (ssit!=nul && smaller(i,smym,*ssit)) smym=*ssit;
        if (mym.h!=INF) fa[i]=n+mym.num,son[n+mym.num].push_back(i); else fa[i]=-1;
        if (smym.h!=INF) fa[n+i]=smym.num,son[smym.num].push_back(n+i); else fa[n+i]=-1;
      }
      scanf("%lld",&x0);
      scanf("%d",&m);
      for (i=2*n;i>=1;i--) if (fa[i]==-1) {
        sum0[i]=sum1[i]=sum2[i]=0;
        maketree(i);
      }
      val=987654322*987654321LL; p=2*n+1;
      h[p]=987654322*987654321LL;
      double s1,s2,ans;
      int end;
      for (i=n+1;i<=2*n;i++) {
        end=dfs(i);
        if (end!=i) {
          s1=sum1[i]-sum1[end]; s2=sum2[i]-sum2[end];
          if (s2==0) ans=INF; else ans=s1/s2;
          if (ans<val || (dengyu(ans,val)&& h[i-n]>h[p])) val=ans,p=i-n;
        }
      }
      printf("%d
    ",p);
      for (i=1;i<=m;i++) {
        scanf("%d %lld",&ss,&x0);
        end=dfs(n+ss);
        printf("%lld %lld
    ",sum1[n+ss]-sum1[end],sum2[n+ss]-sum2[end]);
      }
    }
  • 相关阅读:
    httpd-2.2 配置及用法完全攻略
    在 Ubuntu 16.04 上安装 LEMP 环境之图文向导
    Zookeeper集群搭建
    smem – Linux 内存监视软件
    X.Org可能将失去它的域名x.org
    Docker 容器测试全探索
    Unix操作系统中UUCP知识详细讲解
    常用的Git Tips
    Unix操作系统中UUCP知识详细讲解
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427448.html
Copyright © 2011-2022 走看看