hdu4446 IT Companies

来源:互联网 发布:三星手机数据恢复 编辑:程序博客网 时间:2024/06/09 22:55

HDU 2012'11校赛开始在线报名,欢迎本校同学踊跃参与~

IT Companies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 178    Accepted Submission(s): 48


Problem Description
There are N IT companies which are labeled from 1 to N. Each of them has a branch (a branch is not a company, and companies and branches are all called "unit").The branches are labeled from -1 to –N. The branch of company i is labeled as -i. The number of workers of each company and its branch has to fit the rules below:
1. The number of workers of a company must be larger than that of the branch of it.
2. There are more workers in company i than company j if and only if there are more workers in the branch of company i than the branch of company j.
Among the companies whose label is larger than i(range from i+1 to n),and the branches whose label is larger than -i (range from -1 to –(i-1) ), there are c[i] units which have more workers than company i.
You need to sort the 2×N units in the ascending order by the number of workers.
 

Input
The input contains multiple test cases. Each test case begins with a single line containing one integer N indicating the number of companies (0 < N ≤ 100000). Next line contains N integers which are c[1],c[2]…c[N] (c[i] ≤ N).
The input ends with N = 0.
 

Output
For each test case, output the sorted label sequence of all units in a line. If there are no solutions, output "Impossible" instead.
This problem is special judged.
 

Sample Input
21 1104 8 3 4 2 0 5 7 1 60
 

Sample Output
Impossible-8 -2 -10 -7 8 2 10 -4 7 -1 4 -3 -5 -9 1 3 5 9 -6 6
 


第一次活生生的写了一棵线段树....调了一天代码....不过ac的时候还是好开心啊好开心^-^

构造用的是官方题解:

1.一开始开2个队列a,ba为答案队列,b为临时队列

2.找出当最小的C值为C[k](相同时取k最小的)

a)C[k]=0:将k加入a-k加入b。在C序列中删除元素C[k],并将C[1]C[k-1]减一。

b)C[k]>0:将b队首的元素p取出加入a,并将C[-p+1]c[n]减一。

重复做直到所有元素进入a或者b

3.将b接在a后面,倒序就是答案序列

无解有两种情况:

1C中出现了负数。

2.出现2b情况时b为空

这种构造显然不是我能想到的....我好好把线段树写出来就万岁了...

#include <iostream>#include <queue>#include <cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int ma=1000010;const int inf=1<<25;int n;int c[ma<<2];int rc[ma];int add[ma<<2];int rrt;void pushup(int rt){     c[rt]=min(c[rt<<1],c[rt<<1|1]);}void pushdown(int rt,int m){     if(add[rt])     {         add[rt<<1]+=add[rt];         add[rt<<1|1]+=add[rt];         c[rt<<1]+=add[rt];         c[rt<<1|1]+=add[rt];         add[rt]=0;     }}void build(int l,int r,int rt){     add[rt]=0;     if(l==r)     {           scanf("%d",&c[rt]);           return ;     }     int m=(l+r)>>1;     build (lson);     build (rson);     pushup(rt);} int query(int l,int r,int rt){    if(l==r){rrt=rt;return l;}    pushdown(rt,r-l+1);    int m=(l+r)>>1;    if(c[rt<<1]<=c[rt<<1|1])    return query(lson);    else return query(rson);}void update(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)    {        add[rt]--;        c[rt]--;        return ;    }    pushdown(rt,r-1+1);    int m=(l+r)>>1;    if(L<=m) update(L,R,lson);    if(m<R)update(L,R,rson);     pushup(rt);}void update2(int p,int l,int r,int rt){     if(l==r)     {         c[rt]=inf;         return ;      //   cout<<"update2"<<rt<<endl;     }     int m=(l+r)>>1;     if(p<=m)update2(p,lson);     else update2(p,rson);     pushup(rt);}    int main(){    while(scanf("%d",&n),n)    {        int id=0;        int flag=0;        build(1,n,1);        queue <int> a;        queue <int> b;        while(a.size()+b.size()!=2*n)        {            int qq=query(1,n,1);            //cout<<qq<<" "<<c[rrt]<<endl;            if(c[rrt]<0)            {                    flag=1;break;            }             if(c[rrt]==0)            {                 a.push(qq);              //  cout<<"if"<<rrt<<"qq"<<qq<<endl;                 b.push(-qq);                 if(qq!=1)                 update(1,qq-1,1,n,1);                                  update2(qq,1,n,1);             //    cout<<qq<<" "<<c[rrt]<<endl;             //    cout<<"what"<<c[3]<<endl;            }            else            {              //  cout<<"else"<<b.size()<<endl;                if(b.size()==0){flag=1;break;}                int t=b.front();             //   cout<<"what"<<c[3]<<endl;                if(-t<n)                update(-t+1,n,1,n,1);              // cout<<"what"<<c[3]<<endl;                b.pop();                a.push(t);            }        }        if(flag)        {                printf("Impossible\n");                }else{                      int d[200010];                      int i=0;         while(a.size()!=0)        {d[i++]=a.front();a.pop();}         while(b.size()!=0)        {d[i++]=b.front();b.pop();}         //printf("%d",d[2*n-1]);        for(i=2*n-1;i>=0;i--)        printf("%d ",d[i]);        puts("");        }    }    return 0; }                    

里面各种调代码的痕迹无视就好...一直错在update的时候上下界如果超了,就会出一些奇怪的问题....不知道为什么会出那些问题,不过加上if判断就好了.

写起来就是普通的线段树,不过我用的法子比较笨,同时用了区间更新和单点更新....因为对线段树还是不太熟....其实现在一想用一个应该就够了...update是区间减一,update2是把单点设为无穷大.查询是全部数找最小值.

....这么简单的东西我到底是怎么写了一天的T-T...


顺手把update2这种奇怪的东西弄掉了...

#include <iostream>#include <queue>#include <cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int ma=1000010;const int inf=1<<25;int n;int c[ma<<2];int rc[ma];int add[ma<<2];int rrt;void pushup(int rt){     c[rt]=min(c[rt<<1],c[rt<<1|1]);}void pushdown(int rt,int m){     if(add[rt])     {         add[rt<<1]+=add[rt];         add[rt<<1|1]+=add[rt];         c[rt<<1]+=add[rt];         c[rt<<1|1]+=add[rt];         add[rt]=0;     }}void build(int l,int r,int rt){     add[rt]=0;     if(l==r)     {           scanf("%d",&c[rt]);           return ;     }     int m=(l+r)>>1;     build (lson);     build (rson);     pushup(rt);} int query(int l,int r,int rt){    if(l==r){rrt=rt;return l;}    pushdown(rt,r-l+1);    int m=(l+r)>>1;    if(c[rt<<1]<=c[rt<<1|1])    return query(lson);    else return query(rson);}void update(int L,int R,int l,int r,int rt,int ad){    if(L<=l&&r<=R)    {        add[rt]+=ad;        c[rt]+=ad;        return ;    }    pushdown(rt,r-1+1);    int m=(l+r)>>1;    if(L<=m) update(L,R,lson,ad);    if(m<R)update(L,R,rson,ad);     pushup(rt);}int main(){    while(scanf("%d",&n),n)    {        int id=0;        int flag=0;        build(1,n,1);        queue <int> a;        queue <int> b;        while(a.size()+b.size()!=2*n)        {            int qq=query(1,n,1);            //cout<<qq<<" "<<c[rrt]<<endl;            if(c[rrt]<0)            {                    flag=1;break;            }             if(c[rrt]==0)            {                 a.push(qq);              //  cout<<"if"<<rrt<<"qq"<<qq<<endl;                 b.push(-qq);                 if(qq!=1)                 update(1,qq-1,1,n,1,-1);                                  update(qq,qq,1,n,1,inf);             //    cout<<qq<<" "<<c[rrt]<<endl;             //    cout<<"what"<<c[3]<<endl;            }            else            {              //  cout<<"else"<<b.size()<<endl;                if(b.size()==0){flag=1;break;}                int t=b.front();             //   cout<<"what"<<c[3]<<endl;                if(-t<n)                update(-t+1,n,1,n,1,-1);              // cout<<"what"<<c[3]<<endl;                b.pop();                a.push(t);            }        }        if(flag)        {                printf("Impossible\n");                }else{                      int d[200010];                      int i=0;         while(a.size()!=0)        {d[i++]=a.front();a.pop();}         while(b.size()!=0)        {d[i++]=b.front();b.pop();}         //printf("%d",d[2*n-1]);        for(i=2*n-1;i>=0;i--)        printf("%d ",d[i]);        puts("");        }    }    return 0; }                    



原创粉丝点击