倍增版的, 感受树状数组优美的性质。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<set>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
const int mx = 1e5 + 5;
const int inf = 1<<30;
void fre() {
freopen(".txt", "r", stdin);
freopen(".txt", "w", stdout);
}
int n;
int c[mx], b[mx], a[mx];
int h[mx];
inline int lowbit(int x) { return x & (-x); }
inline void add(int x, int v) {
for( ; x <= n; x += lowbit(x)) c[x] += v;
}
inline int ask(int x) {
int res = 0;
for( ; x > 0; x -= lowbit(x)) res += c[x];
return res;
}
inline int query(int x) {
int ans = 0, sum = 0;
for(int i = 20; i >= 0; i--) {
if(ans + (1<<i) <= n && sum + c[ans+(1<<i)] < x) {
sum += c[ans+(1<<i)];
ans += (1<<i);
}
}
return ans + 1;
}
int main(){
//fre();
cin >> n;
add(1, 1);
for(int i = 2; i <= n; i++) scanf("%d", &a[i]), add(i, 1);
for(int i = n; i >= 1; i--) {
h[i] = query(a[i]+1);
add(h[i], -1);
}
for(int i = 1; i <= n; i++) printf("%d\n", h[i]);
return 0;
}
666。补充一点,树状数组可以做到线性复杂度初始化的。
赞美作者,顺便祝FPX今年夺冠。
哈哈,今年是TES了
哈哈哈,去年edg
优美~
请问一下倍增找完为什么要返回 ans+1
因为我们倍增查询第x个1时的时候, 只有当 ans += 2^p <x 才更新ans, 所以最后ans是比x小1的。 可以手动模拟这个过程理解一下。 就像倍增求lca的时候, 当 x 和 y 的第2^i祖先不相同时才跳, 最后答案是x(y)的父亲, 就像这里的ans+1。