zoukankan      html  css  js  c++  java
  • (线段树/贪心)AtCoder Regular Contest 080 E : Old Maid

    E - Young Maids


    Time limit : 2sec / Memory limit : 256MB

    Score : 800 points

    Problem Statement

    Let N be a positive even number.

    We have a permutation of (1,2,…,N)p=(p1,p2,…,pN). Snuke is constructing another permutation of (1,2,…,N)q, following the procedure below.

    First, let q be an empty sequence. Then, perform the following operation until p becomes empty:

    • Select two adjacent elements in p, and call them x and y in order. Remove x and y from p (reducing the length of p by 2), and insert x and y, preserving the original order, at the beginning of q.

    When p becomes empty, q will be a permutation of (1,2,…,N).

    Find the lexicographically smallest permutation that can be obtained as q.

    Constraints

    • N is an even number.
    • 2≤N≤2×105
    • p is a permutation of (1,2,…,N).

    Input

    Input is given from Standard Input in the following format:

    N
    p1 p2  pN
    

    Output

    Print the lexicographically smallest permutation, with spaces in between.


    Sample Input 1

    Copy
    4
    3 2 4 1
    

    Sample Output 1

    Copy
    3 1 2 4

    用下标从0开始的数组记录数,显然最终能作为开头的一定是下标为偶数的。由于是字典序,很容易想到贪心的想法,即从第一位开始,每一位取尽可能小的。暴力寻找最小的会使整个算法为n^2,复杂度过大,故采用线段树进行优化,维护区间奇数下标、偶数下标的数的最小值,使复杂度降到nlogn。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <utility>
     14 using namespace std;
     15 #define REP(I,N) for (I=0;I<N;I++)
     16 #define rREP(I,N) for (I=N-1;I>=0;I--)
     17 #define rep(I,S,N) for (I=S;I<N;I++)
     18 #define rrep(I,S,N) for (I=N-1;I>=S;I--)
     19 #define FOR(I,S,N) for (I=S;I<=N;I++)
     20 #define rFOR(I,S,N) for (I=N;I>=S;I--)
     21 typedef unsigned long long ull;
     22 typedef long long ll;
     23 //const int INF=0x3f3f3f3f;
     24 const int INF=1e9;
     25 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     26 const ll M=1e9+7;
     27 const ll maxn=1e5+7;
     28 const int MAXN=1005;
     29 const int MAX=2e5+5;
     30 const int MAX_N=MAX;
     31 const ll MOD=1e9+7;
     32 //const double eps=0.00000001;
     33 //ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
     34 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     35 inline ll powMM(ll a,ll b){
     36     ll ret=1;
     37     a%=M;
     38 //    b%=M;
     39     while (b){
     40         if (b&1) ret=ret*a%M;
     41         b>>=1;
     42         a=a*a%M;
     43     }
     44     return ret;
     45 }
     46 int mina[MAX<<2][2];
     47 int a[MAX],lo[MAX],n;
     48 void init(int l,int r,int k)
     49 {
     50     mina[k][0]=mina[k][1]=INF;
     51     if(l==r)
     52         return;
     53     init(l,(l+r)/2,2*k);
     54     init((l+r)/2+1,r,2*k+1);
     55 }
     56 void build(int l,int r,int k)//左闭右闭
     57 {
     58     if(l==r)
     59     {
     60         scanf("%d",&a[l]);
     61         lo[a[l]]=l;
     62         mina[k][l%2]=a[l];return;
     63     }
     64     int mid=(l+r)/2;
     65     build(l,mid,2*k);
     66     build(mid+1,r,2*k+1);
     67     mina[k][0]=min(mina[2*k][0],mina[2*k+1][0]);
     68     mina[k][1]=min(mina[2*k][1],mina[2*k+1][1]);
     69 }
     70 int query(int ql,int qr,int l,int r,int k,int st)
     71 {
     72     if(l>=ql&&r<=qr)
     73         return mina[k][st];
     74     int mid=(l+r)/2;
     75     if(mid<ql)
     76         return query(ql,qr,mid+1,r,2*k+1,st);
     77     else if(mid>=qr)
     78         return query(ql,qr,l,mid,2*k,st);
     79     else
     80         return min(query(ql,qr,l,mid,2*k,st),query(ql,qr,mid+1,r,2*k+1,st));
     81 }
     82 struct node
     83 {
     84     int l,r,xiao,status;
     85     bool operator <(node b)const
     86     {
     87         return xiao>b.xiao;
     88     }
     89     node(int x=0,int y=0,int z=0,int s=0):l(x),r(y),xiao(z),status(s){}
     90 };
     91 priority_queue<node>que;
     92 int an[MAX],cnt;
     93 int main()
     94 {
     95     cnt=0;
     96     scanf("%d",&n);
     97     init(0,n-1,1);
     98     build(0,n-1,1);
     99     node tem;
    100     tem.l=0;tem.r=n-1;tem.xiao=query(0,n-1,0,n-1,1,0);tem.status=0;
    101     que.push(tem);
    102     while(!que.empty())
    103     {
    104         tem=que.top();que.pop();
    105         int now=lo[tem.xiao];
    106         int nxt=query(now+1,tem.r,0,n-1,1,1^tem.status);
    107         int to=lo[nxt];
    108         an[cnt++]=tem.xiao;an[cnt++]=nxt;
    109         if(now>tem.l)
    110             que.push(node(tem.l,now-1,query(tem.l,now-1,0,n-1,1,tem.status),tem.status));
    111         if(to-now>1)//中间的区间奇偶性会变化
    112             que.push(node(now+1,to-1,query(now+1,to-1,0,n-1,1,tem.status^1),tem.status^1));
    113         if(tem.r>to)
    114             que.push(node(to+1,tem.r,query(to+1,tem.r,0,n-1,1,tem.status),tem.status));
    115     }
    116     for(int i=0;i<cnt;i++)
    117         printf("%d ",an[i]);
    118     return 0;
    119 }
  • 相关阅读:
    004-Shell 基本运算符、算术运算符、关系运算符、布尔运算符、辑运算符、字符串运算符、文件测试运算符
    003-shell 传递参数
    002-shell变量定义、使用、字符串替换,分隔,搜索、数组、注释
    【Java】验证码识别解决方案
    bufferedimage 转换成 inputstream并保存文件
    遍历json对象---Java
    【网络爬虫】Httpclient4.X中使用HTTPS的方法采集12306网站
    httpclient获取cookies
    驾考宝典排行榜之爬虫接口解决方案
    java去除字符串中的空格、回车、换行符、制表符
  • 原文地址:https://www.cnblogs.com/quintessence/p/7296407.html
Copyright © 2011-2022 走看看