Codeforces 420D Cup Trick 平衡树

Cup Trick

平衡树维护一下位置。

#include<bits/stdc++.h>
#include <bits/extc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;
using namespace __gnu_pbds;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-6;
const double PI = acos(-1);

template <class T>
using Tree = tree<T, null_type, std::less<T>, rb_tree_tag,tree_order_statistics_node_update>;

Tree<PII> T;

int n, m, ans[N];
bool vis[N];

int main() {
    scanf("%d%d", &n, &m);
    int mn = m;
    for(int i = 1; i <= n; i++)
        T.insert(mk(i + m, i));
    while(m--) {
        int x, y; scanf("%d%d", &x, &y);
        PII p = *T.find_by_order(y - 1);
        T.erase(p);
         p.fi = mn--;
        T.insert(p);
        if(ans[p.se]) {
            if(x != ans[p.se]) return puts("-1"), 0;
        } else {
            if(vis[x]) return puts("-1"), 0;
            ans[p.se] = x;
            vis[x] = true;
        }
    }
    for(int i = 1, j = 1; i <= n; i++) {
        if(!ans[i]) {
            while(vis[j]) j++;
            vis[j] = true;
            ans[i] = j;
        }
        printf("%d ", ans[i]);
    }
    puts("");
    return 0;
}

/*
find_by_order(k - 1) 求第k小的值
order_of_key(k) 求有多少个数 <= k
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10654874.html