zoukankan      html  css  js  c++  java
  • 倍增从入门到入土

    入门

    P1081 [NOIP2012 提高组] 开车旅行

    tj前:看到第一第二大,可以倍增维护,但是这建边也太恶心了,然后对于第一问我在挨个点跑一边?倍增起码有个区间吧,宁给我个 (x_0) 我也不知道该从那么跑哇,只能从头往后排,这不曼斯?
    比值可以模拟,但是这该怎么跑

    tj后:看了看可以模拟,我先试试
    70分暴力模拟

    /*
        c1[i] 距离i最近的城市
        c2[i] 距离i次进的城市 
        dis1[i] 从i到c[i]的距离
        dis2[i] 同理 次二进的 
        A---2
        B---1+ 
    */
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <bits/stdc++.h>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    const int A = 1e7+10;
    const int B = 1e6+10;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    inline int read() {
      char c = getchar();
      int x = 0, f = 1;
      for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
      for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
      return x * f;
    }
    
    int n,m,h[B],xl,p;
    
    int dis1[B],dis2[B],c1[B],c2[B];
    
    double minv=INT_MAX;
    
    main()
    {
        int x,y;
        n=read();
        for (int i=1;i<=n;i++) h[i]=read();
        
        for (int i=n-1;i>=1;i--)
        {
            int minx=i+1,minxx=0;
            dis1[i]=abs(h[i]-h[i+1]);
            for (int j=i+2;j<=n;j++)
            {
                if (dis1[i]>abs(h[i]-h[j]) || (dis1[i]==abs(h[i]-h[j]) && h[j]<h[minx]))
                {
                    minxx=minx;
                    minx=j;
                    dis2[i]=dis1[i];
                    dis1[i]=abs(h[i]-h[j]); 
                }
                else if (dis2[i]==0 || dis2[i]>abs(h[i]-h[j]) || (dis2[i]==abs(h[i]-h[j]) && h[j]<h[minxx]))
                {
                    minxx=j;
                    dis2[i]=abs(h[i]-h[j]);
                }
            }
            c1[i]=minx;
            c2[i]=minxx;
        }
        
        xl=read();
        int ans=0;
        for (int i=1;i<=n;i++)
        {
            int js=0,sum=0,a=0,b=0;
            int s=i;
            while (1)
            {
                
                if(!js)
                {
                    if (a+b+dis2[s]>xl || !c2[s]) break;
                    a+=dis2[s];
                    s=c2[s];
                }
                else
                {
                    if (a+b+dis1[s]>xl || !c1[s]) break;
                    b+=dis1[s];
                    s=c1[s];
                }
                js^=1;
            } 
            if (!ans || 1.0*a / b - minv < -0.00000001 || (fabs(1.0*a / b - minv) <= 0.00000001&&h[ans] < h[i]))
            {
                minv = 1.0*a / b;
                ans = i;
            }
        }
        
        printf("%lld
    ",ans);
        p=read();
        while (p--)
        {
            int w,js=0,a=0,b=0;
            x=read(),y=read();
            int s=x;
            while (1)
            {
                if(!js)
                  {
                    if (a+b+dis2[s]>y || !c2[s]) break;
                    a+=dis2[s];
                    s=c2[s];
                }
                else
                {
                    if (a+b+dis1[s]>y || !c1[s]) break;
                    b+=dis1[s];
                    s=c1[s];
                }
                js^=1;
            }
            printf("%lld %lld
    ",a,b);
        } 
        return 0;
    } 
    
    

    倍增优化,双向链表初始化
    做完我都在想今天晚上我为甚选择的宁,一晚上没了

    /*
        c1[i] 距离i最近的城市
        c2[i] 距离i次进的城市 
        dis1[i] 从i到c[i]的距离
        dis2[i] 同理 次二进的 
        A---2
        B---1+ 
    */
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <bits/stdc++.h>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    const int A = 1e7+10;
    const int B = 1e6+10;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    inline int read() {
      char c = getchar();
      int x = 0, f = 1;
      for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
      for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
      return x * f;
    }
    
    int n,m,h[B],xl,p;
    
    int pos[B],dis1[B],dis2[B],c1[B],c2[B];
    int  c3[B][21],dist3[B][21], dist4[B][21], dist5[B][21];
    
    double minv=INT_MAX;
    
    struct node{int h,bh,last,next;}q[B];
    
    bool cmp(node a,node b){return a.h<b.h;}
    
    void updata(int i,int loc,int x)
    {
        if (x>=1 && x<=n)
            {
                if (!dis1[i] || dis1[i]>abs(q[loc].h -q[x].h) || (dis1[i]==abs(q[loc].h -q[x].h) && q[x].h <q[pos[c1[i]]].h))
                {
                    c2[i]=c1[i];
                    c1[i]=q[x].bh;
                    dis2[i]=dis1[i];
                    dis1[i]=abs(q[loc].h -q[x].h); 
                }
                else if (dis2[i]==0 || dis2[i]>abs(q[loc].h -q[x].h) || (dis2[i]==abs(q[loc].h -q[x].h) && q[x].h <q[pos[c2[i]]].h))
                {
                    c2[i]=q[x].bh;
                    dis2[i]=abs(q[loc].h -q[x].h);
                }
            }
    }
    
    main()
    {
        int x,y;
        n=read();
        for (int i=1;i<=n;i++) q[i].h=read(),q[i].bh=i;
        sort(q+1,q+1+n,cmp);
        
        for (int i=1;i<=n;i++)
        {
            pos[q[i].bh]=i;
            if (i!=1) q[i].last=i-1;
            if (i!=n) q[i].next=i+1;
        }
        
        for (int i=1;i<=n;i++)
        {
            int loc = pos[i];
            updata(i, loc, q[q[loc].last].last);
            updata(i, loc, q[loc].last);
            updata(i, loc, q[loc].next);
            updata(i, loc, q[q[loc].next].next);
            if (q[loc].last)q[q[loc].last].next = q[loc].next;
            if (q[loc].next)q[q[loc].next].last = q[loc].last;
            q[loc].last = q[loc].next = 0;
        }
        
         for ( int i = 1; i <= n; ++i)
        {
            dist4[i][0] = dis2[i];
            dist5[i][0] = dis1[c2[i]];
            dist3[i][0] = dis2[i] + dis1[c2[i]];
            c3[i][0] = c1[c2[i]];
        }
        
        for ( int j = 1; j <= 20; ++j)
            for ( int i = 1; i <= n; ++i)
            {
                c3[i][j] = c3[c3[i][j - 1]][j - 1];
                if (c3[i][j])
                {
                    dist3[i][j] = dist3[i][j - 1] + dist3[c3[i][j - 1]][j - 1];
                    dist4[i][j] = dist4[i][j - 1] + dist4[c3[i][j - 1]][j - 1];
                    dist5[i][j] = dist5[i][j - 1] + dist5[c3[i][j - 1]][j - 1];
                }
            }
        int xx = read(), ans = 0;
        for (int i = 1; i <= n; ++i)
        {
             int a = 0, b = 0, loc = i, x0 = xx;
            for ( int j = 20; j >= 0; --j)
            {
                if (dist3[loc][j] && x0 >= dist3[loc][j])
                {
                    x0 -= dist3[loc][j];
                    a += dist4[loc][j];
                    b += dist5[loc][j];
                    loc = c3[loc][j];
                }
            }
            if (dis2[loc] <= x0)a += dis2[loc];
            if (a <= 0)continue;
            if (!ans || 1.0*a / b - minv < -0.00000001 || (fabs(1.0*a / b - minv) <= 0.00000001&&q[pos[ans]].h < q[pos[i]].h))
            {
                minv = 1.0*a / b;
                ans = i;
            }
        }
        
        printf("%lld
    ",ans);
        p=read();
        while (p--)
        {
             int s = read(), x = read(), a = 0, b = 0;
            for ( int j = 20; j >= 0; --j)
            {
                if (dist3[s][j] && x >= dist3[s][j])
                {
                    x -= dist3[s][j];
                    a += dist4[s][j];
                    b += dist5[s][j];
                    s = c3[s][j];
                }
            }
            if (dis2[s] <= x)a += dis2[s];
            printf("%lld %lld
    ", a, b);
        } 
        return 0;
    } 
    
    
  • 相关阅读:
    【郑轻邀请赛 G】密室逃脱
    【郑轻邀请赛 C】DOBRI
    【郑轻邀请赛 F】 Tmk吃汤饭
    【郑轻邀请赛 I】这里是天堂!
    【郑轻邀请赛 B】base64解密
    【郑轻邀请赛 A】tmk射气球
    【郑轻邀请赛 H】 维克兹的进制转换
    解决adb command not found以及sdk环境配置
    adb shell 命令详解,android, adb logcat
    Unexpected exception 'Cannot run program ... error=2, No such file or directory' ... adb'
  • 原文地址:https://www.cnblogs.com/lToZvTe/p/14525936.html
Copyright © 2011-2022 走看看