2015 ACM/ICPC Asia Regional Hefei Online J.Queue

来源:互联网 发布:怎样用软件阅读趣头条 编辑:程序博客网 时间:2024/05/01 08:34

思路:

按高度从高到低排序,然后插入到第P+1个空位,查找的方法就是树状数组+二分,还有题目要求字典序最小,所以需要判断一下在选择插入的方向。

其实二分有时候写的比较虚,什么L,R啊,不知道返回哪个?(当然是我太弱啦)一种方法就是输出L,R,然后观察决定返回值。另外一种就是实力判断QAQ.

代码:

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <iostream>#include <cmath>#include <map>#include <vector>#include <set>#include <string>#define PB push_back#define FT first#define SD second#define MP make_pair#define INF 0x3f3f3f3fusing namespace std;typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int>  P;const int N=5+1e5,MOD=7+1e9;int n,sum[N],ans[N];P a[N];bool cmp(P x,P y) { return x.FT < y.FT; }void update(int pos,int val){    while(pos<N) {        sum[pos] += val;        pos += (pos&(-pos));    }}int cal(int pos){    int ans=0;    while(pos) {        ans+=sum[pos];        pos -= (pos&(-pos));    }    return ans;}int solve2(int p){    int L=1,R=n;    while(L<=R) {        int mid = (L+R)>>1;        if(mid-cal(mid) >= p) {            R=mid-1;        }        else L=mid+1;    }    //cout<<"2: "<<L<<" "<<R<<endl;    if(L>=1 && L<=n) return L;    return -1;}int solve1(int p){    int L=1,R=n;    while(L<=R) {        int mid = (L+R)>>1;        if((n-mid+1)-(cal(n)-cal(mid-1)) >=p) {            L=mid+1;        }        else R=mid-1;    }    //cout<<"1: "<<L<<" "<<R<<endl;    if(R>=1 && R<=n) return R;    return -1;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T,ca=0;    scanf("%d",&T);    while(T --){        scanf("%d",&n);        memset(sum,0,sizeof(sum));        for(int i=0;i<n;i++){            scanf("%d%d",&a[i].FT,&a[i].SD);        }        sort(a,a+n,cmp);        bool ok = 1;        for(int i=0;i<n;i++){            int t,p=a[i].SD + 1;            if((n-i-p+1) < p) {                t = solve1(p);            }            else {                t = solve2(p);            }            if(t==-1) {                ok = 0;                break;            }            else {                ans[t] = a[i].FT;                update(t,1);            }        }        printf("Case #%d: ", ++ca);        if(!ok) printf("impossible\n");        else {            for(int i=1;i<n;i++) printf("%d ", ans[i]);            printf("%d\n",ans[n]);        }    }    //system("pause");    return 0;}
0 0
原创粉丝点击