• P1081 开车旅行


     P1081 开车旅行

    输入样例#1: 复制
    4 
    2 3 1 4 
    3 
    4 
    1 3 
    2 3 
    3 3 
    4 3
    
    输出样例#1: 复制
    1 
    1 1 
    2 0 
    0 0 
    0 0 
    输入样例#2: 复制
    10 
    4 5 6 1 2 3 7 8 9 10 
    7 
    10 
    1 7 
    2 7 
    3 7 
    4 7 
    5 7 
    6 7 
    7 7 
    8 7 
    9 7 
    10 7
    输出样例#2: 复制
    2 
    3 2 
    2 4 
    2 1 
    2 4 
    5 1 
    5 1 
    2 1 
    2 0 
    0 0 
    0 0

    题解:一道不可做的题;代码+思维
    双向链表,倍增维护次大值最大值
    https://www.luogu.org/problemnew/solution/P1081
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M = 1e5 + 5, P = 19;
    struct edge{int l, r;}lnk[M];
    struct node{
        int id, h;
        bool operator < (const node &rhs) const{
            return h < rhs.h;
        }
    }p[M];
    int rnk[M], nxta[M], nxtb[M], A, B, stA[M][P+1], stB[M][P+1], f[M][P+1];
    inline bool dir(int t){
        if(!lnk[t].l)return 0;
        if(!lnk[t].r)return 1;
        if(p[t].h - p[lnk[t].l].h <= p[lnk[t].r].h - p[t].h)return 1;
        return 0;
    }
    inline int pd(int t, int a, int b){
        if(!a || !b)return p[a + b].id;
        if(p[t].h - p[a].h <= p[b].h - p[t].h) return p[a].id;
        return p[b].id;
    }
    inline int ab(int a, int b){return a >= b ? a - b : b - a;}
    
    void drive(int st, int lim){
        A = 0, B = 0;
        int tmp = lim;
        for(int o = P; o >= 0; o--)
            if(f[st][o] && (long long) A + B + stA[st][o] + stB[st][o] <= tmp)
                A += stA[st][o], B += stB[st][o], st = f[st][o];
        if(nxta[st] && A + B + stA[st][0] <= tmp) 
            A += stA[st][0];
    }
    int read(){
        int x = 0; int f = 1; char c = getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
        return x*=f;
    }
    
    int main(){
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) p[i].h = read(), p[i].id = i;
        sort(p + 1, p + 1 + n);
        for(int i = 1; i <= n; i++) rnk[p[i].id] = i;
        for(int i = 1; i <= n; i++) lnk[i].l = i - 1, lnk[i].r = i + 1;
        lnk[1].l = 0, lnk[n].r = 0;
        for(int i = 1; i <= n; i++) {
            int t = rnk[i];
            bool fg = dir(t);
            if(fg) nxtb[i] = p[lnk[t].l].id, 
            nxta[i] = pd(t, lnk[lnk[t].l].l, lnk[t].r);
            else nxtb[i] = p[lnk[t].r].id,
            nxta[i] = pd(t, lnk[t].l, lnk[lnk[t].r].r);
            if(lnk[t].r) lnk[lnk[t].r].l = lnk[t].l;
            if(lnk[t].l) lnk[lnk[t].l].r = lnk[t].r;
        }
        for(int i = 1; i <= n; i++){
            f[i][0] = nxtb[nxta[i]];
            stA[i][0] = ab(p[rnk[nxta[i]]].h, p[rnk[i]].h);
            stB[i][0] = ab(p[rnk[f[i][0]]].h, p[rnk[nxta[i]]].h);
        }
        for(int o = 1; o <= P; o++)
            for(int i = n; i; i--){
                f[i][o] = f[f[i][o-1]][o-1];
                stA[i][o] = stA[i][o-1] + stA[f[i][o-1]][o-1];
                stB[i][o] = stB[i][o-1] + stB[f[i][o-1]][o-1];
            }
        int X0 = read();
        double tmp = 2e9;
        int id = -1;
        for(int i = 1; i <= n; i++){
            drive(i, X0);
            if(B && 1.0*A/B < tmp){
                tmp = 1.0*A/B; id = i;
            }
            else if(B && 1.0*A/B == tmp && rnk[i] > rnk[id]) id = i;
        }
        printf("%d
    ",id);
        int m = read();
        while(m--){
            int st = read(), x = read();
            drive(st, x);
            printf("%d %d
    ", A, B);
        }
        
    }
    View Code
    
    
    
     
  • 相关阅读:
    java三层架构:持久层、业务层、表现层
    Spring:Spring JDBCTemplate & 声明式事务
    Spring:AOP
    Spring:IOC控制反转
    Mybatis: 加载策略及注解开发
    Mybatis 配置文件深入
    Mybatis:基本应用
    前后端项目接口联调
    springboot整合jsp
    IDEA出现URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9904858.html
Copyright © 2020-2023  润新知