[CSP]奇妙なレースシミュレーションキュー(フェンウィックツリー&半分&貪欲)

タイトル説明

あまりにも多くのnodgdファンは、毎日多くの人がサインのために並んで。
今日があるのn人々がラインアップ、一人一人の高さは整数であり、互いに異なります。非常に残念ながら、私は行くために、今日他のことで忙しいnodgd、彼らはこれらのファンは明日戻って来るようしなければなりませんでした。一方nodgd要求をした、一人一人が自分の目の前にし、数が明日への今日の秩序を回復するために、自国民よりも高くなることを覚えておく必要があります。
ただし、一部のファンは、すでに「前」でどちら側伝えることができなかったので、彼らはおそらく自分自身の人の前よりに番号を覚えて、多かれ少なかれ失望、魅了、彼らは混乱し、混乱有効に失望していますそれ自体よりも高いの背中の番号を覚えておくことができ、彼らは知らないどの方向を覚えておくことです。
いずれかに2つの方向は、少なくとも数は彼の一つの方向よりも高くなると、彼は同じ図を思い出したように、たとえそうであっても明日は、キュー内の秩序を回復することができ、考えるnodgd。残念ながら、nが解決するプログラムを書くための明確な必要性、nodgd忙しい書き込みプログラムあなたへのこの種のものは、比較的大きいです。

入力形式

入力整数nの最初の行、命令の数。(N <= 100000は、高範囲の整数で)
次のn二つの整数のラインはAI、BI、それは人の高さを表し、彼女は数が互いに異なる高さを確保思い出し。

出力フォーマット

出力ライン、高さに皆の前で待ち行列。辞書順最小出力を満たすために意図質問に複数回答がある場合。あなたはタイトルの配置の意味を満たしている場合、出力は「不可能」は存在しません。

サンプル入力

4
4 1
3 1
6 0
2 0

サンプル出力

2436は、
プロンプト
4つの個別の権利個々 1の第2の高さ; 0は彼の前、彼は第四の個々の入力であるよりも、個々の高い回答指定されたキューは、まず個々 2の高さを、彼より背が高いので、彼は最初の個別入力された; 3の第三高さは、右側の彼よりも一人であり、彼は最初の二人の個人が入力された、6の4人目の高さ、0は彼の個人よりも左高いので、彼は第三の個別入力されています。
配置がある場合は明らかに、「6342」は、タイトルの意味を満たすためにもですが、ない最小の辞書順

分析

  莫大な問題のアイデアは、私は口胡Yiboを強制するつもりです

  すなわち、現在の男性が提唱しようと、それは挿入時に貪欲辞書順最小を制御することができますので、可能な限り、小から大まで挿入することを検討してください。

  私たちは皆のための第1プリアウト、どのように多くの個人、彼女は小さい数よりも人の数よりも高い場合、彼女は、彼女は何の解決策を覚えていないよりも背が高いです。

  彼女の前で個人の最小数を計算することが可能で、彼女はKであると想定されるよりも、

  それは彼女によりk空間の前に予約しなければならないので、彼女は、大小規模の挿入ので、挿入されたときに、彼女は最初のkである+ 1人の欠員で

  これが唯一の解決策を保証しません、我々はまた、最低限の辞書式順序を保証することができます。

  インサートの背面は寄与しない空間を占めることができるしかし、人間の存在の同じレベルならば、より多くのk空間の前方に確保することができます

  同じ高さの2人は、最初に挿入された高齢者をK、より小さなKを挿入した後、予約されたスペースの外に大きなKを破壊するであろう小さな人々をk個の場合つまり、

  示されるように、1番と2番の高さが等しく、k個のK = 1番2番= 5,2であります

 

 

  Kを挿入するとき、彼女の男性よりも高くに1番は空孔を残し

 

 

 

  しかし、第2のインサートは、スペースを占有する時期貢献していません

  最初のインサート2のインサート1は、問題は存在しません。

 

 

 

  だから、あなたはそれを挿入した後、大量注文に小さなkだけ同じ高さに遭遇したとき。

  そこで問題は、どのように我々はそれを達成しますか?

  私たちは木を維持するために、配列を使用することができます

  各空間は1であるので、プレフィックスは位置と前にこの位置と空孔の総数であります

  明らかに右の接頭辞と単一成長している、k番目のバイナリ位置欠陥を決定することが可能です

  人が挿入されると、最初の二つは、第一スロットk + 1つの位置、アンサーに分割し、次にツリーにおけるアレイの位置の値を変更し、次の人が再び挿入されています

  复杂度为O(nlog^2n)。好像树状数组还有nlogn的做法,但我想咕了。

  代码

#include<cstdio>
#include<algorithm>
using namespace std;
int n,vis[100005],bit[100005],ans[100005];
struct node{int h,id;}st[100005];
void add(int x,int k){for(;x<=n;x+=(x&-x))bit[x]+=k;}
bool cmp(node a,node b){return a.h==b.h?a.id<b.id:a.h<b.h;}
int que(int x){int s=0;for(;x;x-=(x&-x))s+=bit[x];return s;}
int main()
{
    scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&st[i].h,&st[i].id);
    sort(st+1,st+1+n,cmp);int flag=0;
    for(int i=1,l,r;i<=n;add(i,1),i++)
    {
        l=r=i;while(st[i].h==st[i+1].h)i++,r++;
        for(int j=l;j<=r;j++)flag|=(st[j].id=min(n-r-st[j].id,st[j].id))<0;
    }
    if(flag)return puts("impossible"),0;sort(st+1,st+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        int l=1,r=n,mid,pos;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(que(mid)>=st[i].id+1)r=mid-1,pos=mid;
            else l=mid+1;
        }
        add(pos,-1);
        ans[pos]=st[i].h;
    }
    for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');
}

 

おすすめ

転載: www.cnblogs.com/firecrazy/p/11654827.html