2017 ACM/ICPC Asia Regional Qingdao Online Brute Force Sorting

来源:互联网 发布:淘宝客服转化率怎么算 编辑:程序博客网 时间:2024/06/05 18:32

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=6215

题目大意:给出一个序列,一种操作: 对于当前数列中所有满足a[ i ]>a [  i+1 ]  ( i<n)的i,同时删去所有的a[i]和a[i+1]。

操作执行到无法执行时停止,求最终的序列。

这题有个显然的性质:每个元素最多被删除一次。

利用这个性质,如果建立一个队列,队列内存所有a [ x ] - a[ pre[x] ]<0的 x和pre[x] 值,然后把这些x,pre[x]标记为即将被删去,一起删去,然后利用链表结构来维护删除后现存的前后关系,再把新产生的a [ x ] - a[ pre[x] ]<0的 x和pre[x] 值加入队列, 一直重复操作直到队列为空时停止。

因为加入队列的值一定会被删去,而一个值最多被重复删去2次,所以时间复杂度是O(n)的。

代码:

#include <bits/stdc++.h>using namespace std;inline void read(int &x){    char ch;    bool flag=false;    for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());    x=flag?-x:x;}inline void read(long long &x){    char ch;    bool flag=false;    for (ch=getchar();!isdigit(ch);ch=getchar())if (ch=='-') flag=true;    for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());    x=flag?-x:x;}const int MAXN = 120000;struct zy{int st,ed;    zy( int st,int ed):st(st),ed(ed){}    zy(){}};vector< zy > Q;int n;int a[ MAXN ];bool vis[ MAXN ];bool use[ MAXN ];int pre[ MAXN ];int nex[ MAXN ];int ans[ MAXN ];vector< pair<int , int > > T;void Delete(int x){int a=pre[x];int b=nex[x];pre[ b ]= a;nex[ a ]= b;}void doit(){read(n);for (int i=1;i<=n;i++)    read(a[i]);memset( vis , 0 ,sizeof( vis ));vis[0]=1; vis[n+1]=1;for (int i=1;i<=n;i++){    pre[i]=i-1;    nex[i]=i+1;}Q.clear();for (int i=2;i<=n;i++)    if ( a[i]-a[i-1] <0 )        Q.push_back( zy( i-1 ,i ) );while ( !Q.empty() ){    while ( !Q.empty() )    {        zy tmp;        tmp = Q.back();        Q.pop_back();        int x2=tmp.st;        int x3=tmp.ed;        T.push_back( make_pair(x2,x3 ) );    }    if (T.empty() )        break;    for (auto S:T)        {            int x=S.first;            int y=S.second;            if (!vis[x])                Delete(x);            if (!vis[y])                Delete(y);            vis[ x ] = 1; vis[ y ] = 1;        }    for (auto S:T)        {            int x=S.first;            int y=S.second;            int t1=pre[x];            int t2=nex[t1];            if ( ( ( !vis[ t1 ] ) && ( !vis[ t2 ] ) ) && ( a[t2]-a[t1]<0) )                Q.push_back( zy ( t1 , t2  ) );        }    T.clear();}int cnt=0;for (int i=1;i<=n;i++)    if ( vis[ i ]==0)        ans[++cnt]=a[i];printf("%d\n",cnt);for (int i=1;i<=cnt;i++)    printf("%d ",ans[i]);puts("");}int main(){    int T;    read(T);    for (int i=1;i<=T;i++)        doit();    return 0;}


阅读全文
0 0
原创粉丝点击