POJ

来源:互联网 发布:什么软件测八卦 编辑:程序博客网 时间:2024/06/05 17:48

题意

输入队伍长度n
接下来n行,a,b 表示b插在队伍的a处
求队伍最后的情况

题解

刚开始并不知道要用线段树,经大佬点悟,发现最后插入的位置就是对应的a。所以可以从后往前依次插入,每次的位置pos即找到一个位置pos使它前面空出pos个位置。然后我们就可以用线段树了。
常数巨大的丑陋代码

# include <stdio.h># include <stdlib.h># include <iostream># include <string.h># include <algorithm>using namespace std;# define IL inline# define RG register# define UN unsigned# define ll long long# define rep(i, a, b) for(RG int i = a; i <= b; i++)# define per(i, a, b) for(RG int i = b; i >= a; i--)# define uev(e, u) for(RG int e = ft[u]; e != -1; e = edge[e].nt)# define mem(a, b) memset(a, b, sizeof(a))# define max(a, b) ((a) > (b)) ? (a) : (b)# define min(a, b) ((a) < (b)) ? (a) : (b)const int MAXN = 200001, MAXM = 1000001;struct Tree{    int l, r, num;} tree[MAXM];int n, ans, pos[MAXN], val[MAXN], a[MAXN];IL void Updata(RG int now){    tree[now].num = tree[now<<1].num+tree[now<<1|1].num;}IL void Build(RG int now, RG int l, RG int r){    tree[now] = (Tree) {l, r, 1};    if(l == r) return;    RG int mid = l+r>>1;    Build(now<<1, l, mid); Build(now<<1|1, mid+1, r);    Updata(now);}IL int Query(RG int now, RG int x){    if(tree[now].l == tree[now].r) return tree[now].r;    if(x <= tree[now<<1].num) return Query(now<<1, x);    else return Query(now<<1|1, x-tree[now<<1].num);}IL void Add(RG int now, RG int x){    if(tree[now].l == tree[now].r){        tree[now].num = 0;        return;    }    RG int mid = tree[now].l+tree[now].r>>1;    if(mid < x) Add(now<<1|1, x);    if(mid >= x) Add(now<<1, x);    Updata(now);}int main(){    while(~scanf("%d", &n)){        Build(1, 1, n);        rep(i, 1, n) scanf("%d%d", &pos[i], &val[i]), pos[i]++;        per(i, 1, n){            RG int t = Query(1, pos[i]);            a[t] = val[i];            Add(1, t);        }        rep(i, 1, n) printf("%d ", a[i]);        printf("\n");    }    return 0;}

scanf前没写~居然TLE了三次

原创粉丝点击