zoukankan      html  css  js  c++  java
  • 多校第4场1012

    理解题意以后会发现时比较简单的线段树,理解题意以后首先应该想到一个贪心,就是再寻找最终答案的第i个数时,饿哦们要尽量使这个数尽可能大。那么我们找[1,pos[i]+1]这个区间中已经组队的位置的最大值,记为l,然后找[l+1pos[i]+1]之间未被找过的最大的数。(这里组队的意思是可以详见程序,并不是被找过了)。然后注意一下细节,是一个比较好维护的线段树,复杂付就是线段树的复杂度o(nlogn)。

    题解上写维护组队的右端点是用set维护的,比赛当时也想到了用set维护,但是后来感觉好像只需要把PushUp和Modify稍加修改就好了,但是改了一下,感觉有点烦,索性就复制,粘贴,多谢了2个函数(几乎一样的)。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define FOR(i,x,y)  for(int i = x;i < y;i ++)
    #define IFOR(i,x,y) for(int i = x;i > y;i --)
    #define ll long long
    #define lrt rt<<1
    #define rrt rt<<1|1
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define N 100010
    
    using namespace std;
    
    int pos[N],num[N],ans[N],n;
    bool vis[N];
    
    struct Tree{
        int l,r;
        int maxx,en_maxx;
    }tree[N<<2];
    
    void PushUp(int rt){
        tree[rt].maxx = max(tree[lrt].maxx,tree[rrt].maxx);
    }
    
    void Build(int rt,int l,int r){
        tree[rt].l = l; tree[rt].r = r; tree[rt].maxx = -1,tree[rt].en_maxx = 0;
        if(l == r){
            tree[rt].maxx = num[l];
            return;
        }
        int mid = (l+r)>>1;
        Build(lson);
        Build(rson);
        PushUp(rt);
    }
    
    void Modify(int rt,int k){
        if(tree[rt].l == tree[rt].r){
            tree[rt].maxx = -1;
            return;
        }
        int mid = (tree[rt].l+tree[rt].r)>>1;
        if(k <= mid) Modify(lrt,k);
        else Modify(rrt,k);
        PushUp(rt);
    }
    
    int Query(int rt,int l,int r){
        if(tree[rt].l == l && tree[rt].r == r)    return tree[rt].maxx;
        int mid = (tree[rt].l + tree[rt].r)>>1;
        if(r <= mid) return Query(lrt,l,r);
        else if(l > mid)    return Query(rrt,l,r);
        else{
            return max(Query(lson),Query(rson));
        }
    }
    
    int Query_en(int rt,int l,int r){
        if(tree[rt].l == l && tree[rt].r == r)  return tree[rt].en_maxx;
        int mid = (tree[rt].l + tree[rt].r)>>1;
        if(r <= mid) return Query_en(lrt,l,r);
        else if(l > mid)    return Query_en(rrt,l,r);
        else{
            return max(Query_en(lson),Query_en(rson));
        }
    }
    
    void PushUp_en(int rt){
        tree[rt].en_maxx = max(tree[lrt].en_maxx,tree[rrt].en_maxx);
    }
    
    void Modify_en(int rt,int k){
        if(tree[rt].l == tree[rt].r){
            tree[rt].en_maxx = tree[rt].l;
            return;
        }
        int mid = (tree[rt].l+tree[rt].r)>>1;
        if(k <= mid) Modify_en(lrt,k);
        else Modify_en(rrt,k);
        PushUp_en(rt);
    }
    
    int main()
    {
        //freopen("test.in","r",stdin);
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            FOR(i,1,n+1){
                scanf("%d",&num[i]);
                pos[num[i]] = i;
                ans[i] = -1;
                vis[i] = false;
            }
            Build(1,1,n);
            FOR(i,1,n+1){
                if(ans[i] != -1) continue;
                int r = pos[i];
                int l = Query_en(1,1,r)+1;
                //if(i == 2)
                   // printf("hahah
    ");
                if(l > r)   ans[i] = ans[i+1];
                else{
                    int tem = Query(1,l,r);
                    if(r == n)  ans[i] = tem;
                    else{
                        if(!vis[num[pos[i]+1]]){
                            ans[i] = max(tem,num[pos[i]+1]);
                        }
                        else ans[i] = tem;
                    }
                }
                vis[ans[i]] = true;
                Modify(1,pos[ans[i]]);
                if(pos[ans[i]] <= pos[i])
                    Modify_en(1,pos[i]);
                if(pos[ans[i]] < pos[i]){
                    FOR(j,pos[ans[i]],pos[i]){
                        ans[num[j]] = num[j+1];
                        vis[ans[num[j]]] = true;
                        Modify(1,pos[ans[num[j]]]);
                    }
                }
            }
            printf("%d",ans[1]);
            FOR(i,2,n+1){
                printf(" %d",ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    OpenID Connect 验证
    升级到 .NET Core 3.1
    深入 .NET Core 基础
    依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化
    依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection
    依赖注入在 dotnet core 中实现与使用:1 基本概念
    ng-bootstrap 组件集中 tabset 组件的实现分析
    一笔百亿美元军方订单,引发了美国科技公司大混战
    4种事务的隔离级别,InnoDB怎样巧妙实现?
    Google I/O 官方应用中的动效设计
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4811900.html
Copyright © 2011-2022 走看看