zoukankan      html  css  js  c++  java
  • 【Atcoder】ARC 080 E

    【算法】数学+堆

    【题意】给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序。

    【题解】

    转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前序列的奇数位置,p2在当前序列的偶数位置且位于p1之后。满足条件的情况下每次找最小。

    每次找到p1和p2都把序列划分为3部分,递归进行,初步想到使用归并。

    进一步考虑性质,每对数字要出现必须它的上属序列的p1和p2必须出现,此外没有其他要求。

    所以用优先队列维护每个序列,序列的优先级为p1,每次处理一个序列才能加入其三个子序列。

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn=200010,inf=0x3f3f3f3f;
    int a[maxn],n,logs[maxn],d[2][maxn][30],pos[maxn];
    struct cyc{
        int l,r,x;
        bool operator <(const cyc &a)const
        {return x>a.x;}
    };
    priority_queue<cyc>q;
    
    void RMQ_INIT(int k){
        for(int j=1;(1<<j)<=n;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                d[k][i][j]=min(d[k][i][j-1],d[k][i+(1<<(j-1))][j-1]);
    }
    int rmq(int l,int r,int k){
        int K=logs[r-l+1]; 
         return min(d[k][l][K],d[k][r-(1<<K)+1][K]);
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            d[i&1][i][0]=a[i];//1奇数 
            d[(i&1)^1][i][0]=inf;//0偶数 
            pos[a[i]]=i;//因为是排列可以直接记位置,省去RMQ的位置记录。 
        }
        logs[0]=-1;for(int i=1;i<=n;i++)logs[i]=logs[i>>1]+1;
        RMQ_INIT(0);RMQ_INIT(1);
        q.push((cyc){1,n,rmq(1,n,1)});
        int L,R,p1,p2;
        while(!q.empty()){
            cyc x=q.top();q.pop();
            L=x.l;R=x.r;p1=pos[x.x];
            p2=pos[rmq(p1+1,R,(p1&1)^1)];
            printf("%d %d ",a[p1],a[p2]);
            if(L<p1)q.push((cyc){L,p1-1,rmq(L,p1-1,(L&1))});
            if(p1<p2-1)q.push((cyc){p1+1,p2-1,rmq(p1+1,p2-1,(p1+1)&1)});
            if(p2<R)q.push((cyc){p2+1,R,rmq(p2+1,R,(p2+1)&1)});
        }
        return 0;
    }
    View Code
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Spring|SpringMVC中的注解
    Spring Boot
    Java模板引擎Freemarker
    Spring Boot整合Spring Data JPA
    Java性能优化,操作系统内核性能调优,JYM优化,Tomcat调优
    将字符串进行md5加密
    equals()方法和hashCode()方法
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7355801.html
Copyright © 2011-2022 走看看