羅区P2286 [HNOI2004]ペットの養子縁組フィールド

羅区P2286 [HNOI2004]ペットの養子縁組フィールド

説明

  • ファンファンは、ペットの養子縁組のフィールドをオープンしました。捨てられたペットの飼い主の採用をし、これらのペットを採用する新しい所有者を聞かせて:養子縁組フィールドには、2つのサービスを提供しています。

    それぞれの採用は、彼自身の発明の特別な式を介した要件ファンファンの採用によると、自分のペットの満足度を採用したいと考え、採用はペットの養子縁組値の所望の特性を(aは正の整数であり、取得します<2 ^ 31)、彼はペットの特性値の各フィールドに採用。あまりにもあまりまたは人に放棄ペットペットを採用したい、とペット:このように、彼は簡単に、ペットの養子縁組フィールドは常に2つの事が起こるがあるだろうペットの養子縁組のプロセス全体を扱うことができるようになります。

    あまりにも多くの捨てられたペットは、人の到着は、採用はペットの特性を採用したい場合は採用があり、それはペットの養子縁組を採用することになります場合は、ペットに最も近い特性値で、現在ではありません。その2匹のペットすなわち存在、次の2匹のペットを持っている場合、要件を満たす(任意の特性値の二つのペットは同じにすることはできません、値の特性の2人の採用ペットの養子縁組のいずれかの希望は同じにすることはできません) ABと+ bの特性値が、その後、採用者の特性の値は、ABのペットの鳥を採用します。

    養子縁組のペットの飼い主は、あまりにも、採用されたペットの到着は、それができるとなっている採用がそれを採用する場合は?ペットの特性値が、彼らが望む二人の存在は、ABのペットの採用値の特性を採用する場合は、値に最も近いのが望ましい採用のペットの養子縁組ペット特徴である値を採用を採用することが可能ですそして、A + B、ペットの採用AB成功した採用の特性、値。

    養子自体はペットの特性を採用したい、ペットの特性値を採用し、その後、そのABSの採用(AB)不満Bです。

    あなたが年を取得、養子縁組ペット採用の到着の採用や状況は、あなたがすべてのペットの採用の採用度と満足していない合計を計算してください。最初の年、養子縁組のペットでも採用する場合もありません。

入力

  • 最初の行は、正の整数nはn <= 80000、フィールドに来たペットの養子縁組と年の採用の総数を表します。今年の到着時間の順序に従って次のn行は、養子縁組やペットの採用者の分野での状況を説明するようになりました。各行は= 0はPETを表し、A = 1が採用を表し、bは、2つの正の整数であり、Bは、ペット採用の採用により、特性値または目標値を特徴とするペットを表します。(の採用で同じ時間滞在、またはすべてのペットやすべての採用では、これらのペットと養子縁組の数が1万人以上ではありません)

出力

  • 今年、すべての養子縁組の結果を表す唯一の正の整数は、採用のペット和のmod 1000000将来の度合いに満足していません。

サンプル入力

5                  

0 2                      

0 4                         

1 3

1 2

1 5

サンプル出力

3

注:abs(3-2) + abs(2-4)=3,

最后一个领养者没有宠物可以领养。

ソリューション:

  • これは私が書いた最初のアプリケーションTreapトピックで、より古典的な、繰り返し精査が必要です。
  • この質問は、アイデアは非常に単純な質問を押すことでシミュレートすることを意図しています。しかし、最近の体重の重みから探しての重量見つけることです前駆体後継ああ!2つのTreapを開くことが可能です。マスター・レコード、レコードペット。すべてのペットの所有者でTreapに最高の1で前任者と後継者を見つけ、それを削除するには、すべてのペットにマスターTreapで最高の1で後継者と前任者を見つけ、それを削除します。あなたはマスターに来た場合は、ペットTreapは空である、それはマスターTreapにマスターに追加されます。ペットの共感。このような問題を解決することができます。
  • しかし、唯一のようTreapを開く必要があり、観察。Treapペットそれは空ではありませんのでTreapは、言い換えれば、Treapが空で常にある、いつでも空である所有者があります。だから我々は、現在のTreap Treapやペットの飼い主Treapを記録し、その後、更新、削除、またはに追加することができます。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define N 80005
#define mod 1000000
#define LL long long
using namespace std;

struct T {LL val, dat, l, r, cnt;} t[N];
LL n, tim1, tim2, ans, tot, root, inf = 2147483648 + 1;

LL New(LL val)
{
    t[++tot].val = val, t[tot].dat = rand();
    t[tot].cnt = 1;
    return tot;
}

void zig(LL &y)
{
    LL x = t[y].l;
    t[y].l = t[x].r, t[x].r = y, y = x;
}

void zag(LL &x)
{
    LL y = t[x].r;
    t[x].r = t[y].l, t[y].l = x, x = y;
}

void insert(LL &p, LL val)
{
    if(!p) {p = New(val); return;}
    if(val == t[p].val) {t[p].cnt++; return;}
    if(val < t[p].val)
    {
        insert(t[p].l, val);
        if(t[t[p].l].dat > t[p].dat) zig(p);
    }
    else
    {
        insert(t[p].r, val);
        if(t[t[p].r].dat > t[p].dat) zag(p); 
    }
}

LL nextPre(LL val, LL tag)
{
    LL ans = tag == 0 ? 2 : 1, p = root;
    while(p)
    {
        if(val == t[p].val)
        {
            if(!tag && t[p].l)
            {
                p = t[p].l;
                while(t[p].r) p = t[p].r;
                ans = p; break;
            }
            else if(!tag) break;
            if(tag && t[p].r)
            {
                p = t[p].r;
                while(t[p].l) p = t[p].l;
                ans = p; break;
            }
            else if(tag) break;
        }
        if(!tag && t[p].val < val && t[p].val > t[ans].val) ans = p;
        if(tag && t[p].val > val && t[p].val < t[ans].val) ans = p;
        p = val < t[p].val ? t[p].l : t[p].r;
    }
    return t[ans].val;
}

void erase(LL &p, LL val)
{
    if(!p) return;
    if(val == t[p].val)
    {
        if(t[p].cnt > 1) {t[p].cnt--; return;}
        if(t[p].l || t[p].r)
        {
            if(!t[p].r || t[t[p].l].dat > t[t[p].r].dat)
                zig(p), erase(t[p].r, val);
            else
                zag(p), erase(t[p].l, val);
        }
        else p = 0;
        return;
    }
    val < t[p].val ? erase(t[p].l, val) : erase(t[p].r, val);
}

int main()
{
    New(inf), New(-inf), t[1].l = 2, root = 1;
    cin >> n;
    for(LL i = 1; i <= n; i++)
    {
        LL a, b;
        scanf("%lld%lld", &a, &b);
        if(!a)
        {
            tim1++; 
            if(!tim2) insert(root, b);
            else
            {
                LL v1 = nextPre(b, 0), v2 = nextPre(b, 1);
                if(abs(v1 - b) < abs(v2 - b))
                {
                    ans += abs(v1 - b), ans %= mod;
                    erase(root, v1);
                }
                else if(abs(v1 - b) == abs(v2 - b))
                {
                    ans += abs(v1 - b), ans %= mod;
                    erase(root, v1);
                }
                else
                {
                    ans += abs(v2 - b), ans %= mod;
                    erase(root, v2);
                }
                tim1--, tim2--;
            }
        }
        else
        {
            tim2++;
            if(!tim1) insert(root, b);
            else
            {
                LL v1 = nextPre(b, 0), v2 = nextPre(b, 1);
                if(abs(v1 - b) < abs(v2 - b))
                {
                    ans += abs(v1 - b), ans %= mod;
                    erase(root, v1);
                }
                else if(abs(v1 - b) == abs(v2 - b))
                {
                    ans += abs(v1 - b), ans %= mod;
                    erase(root, v1);
                }
                else
                {
                    ans += abs(v2 - b), ans %= mod;
                    erase(root, v2);
                }
                tim1--, tim2--;
            }
        }
    }
    cout << ans;
    return 0;
}

おすすめ

転載: www.cnblogs.com/BigYellowDog/p/11267153.html