题意
输入队伍长度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("
");
}
return 0;
}
scanf前没写~居然TLE了三次