poj 2182

线段树代码:

(1.普通二叉树,0ms)

#include<stdio.h>
struct {
    int l,r,len;
}tree[8005<<2];
int pre[8005],ans[8005];
void buildtree(int left,int right,int u) {
    tree[u].l=left;
    tree[u].r=right;
    tree[u].len=right-left+1;
    if(left==right)    return;
    buildtree(left,left+right>>1,u<<1);
    buildtree((left+right>>1)+1,right,(u<<1)+1);
}
int query(int u,int num) {
    --tree[u].len;
    if(tree[u].l==tree[u].r)    return tree[u].l;
    if(tree[u<<1].len<num)    return query((u<<1)+1,num-tree[u<<1].len);
    else return query(u<<1,num);
}
int main() {
    int n;
    scanf("%d",&n);
    pre[1]=0;
    for(int i=2;i<=n;++i)    scanf("%d",&pre[i]);
    buildtree(1,n,1);
    for(int i=n;i>=1;--i)    ans[i]=query(1,pre[i]+1);
    for(int i=1;i<=n;++i)    printf("%d\n",ans[i]);
    return 0;
}

(2.满二叉树,94ms,推荐---下标检索比指针快)

#include<stdio.h>
#include<math.h>
int pre[8005],ans[8005],tree[8005<<2];
void buildtree(int n,int left) {
    for(int i=left;i<left+n;++i) tree[i]=1;
    while(left!=1) {
        for(int i=left/2;i<left;++i)
            tree[i]=tree[i<<1]+tree[(i<<1)+1];
        left=left/2;
    }
}
int query(int u,int num,int left) {
    --tree[u];
    if(u>=left)    return u;
    if(tree[u<<1]<num)    return query((u<<1)+1,num-tree[u<<1],left);
    else return query(u<<1,num,left);
}
int main() {
    int left,n;
    scanf("%d",&n);
    pre[1]=0;
    left=1<<(int(log(n)/log(2))+1);
    for(int i=2;i<=n;++i)    scanf("%d",&pre[i]);
    buildtree(n,left);
    for(int i=n;i>=1;--i)
        ans[i]=query(1,pre[i]+1,left)-left+1;
    for(int i=1;i<=n;++i)    printf("%d\n",ans[i]);
    return 0;
}

树状数组代码:

(79ms)

#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int tree[10000],pre[10000],ans[10000];
int n;
#define lowbit(x)    ((x)&-(x))
void add(int x,int d) {
    while(x<=n) {
        tree[x]+=d;
        x+=lowbit(x);
    }
}
int sum(int x) {
    int sum=0;
    while(x) {
        sum+=tree[x];
        x-=lowbit(x);
    }
    return sum;
}
int findpos(int x) {
    int l=1,r=n;
    while(l<r) {
        int mid=(l+r)>>1;
        if(sum(mid)<x)    l=mid+1;
        else    r=mid;
    }
    return l;
}
int main() {
    scanf("%d",&n);
    pre[1]=0;
    for(int i=2;i<=n;++i)    scanf("%d",&pre[i]);
    for(int i=1;i<=n;++i)    tree[i]=lowbit(i);
    for(int i=n;i>0;--i) {
        int x=findpos(pre[i]+1);
        add(x,-1);
        ans[i]=x;
    }
    for(int i=1;i<=n;++i)    printf("%d\n",ans[i]);
    return 0;
}

poj 3468

线段树代码:

#include<stdio.h>
#define ll long long
using namespace std;
ll sum[100001<<2],add[100001<<2];
inline void push_up(int rt) {
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int m) {
    if(add[rt]) {
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        sum[rt<<1]+=(m-(m>>1))*add[rt];
        sum[rt<<1|1]+=(m>>1)*add[rt];
        add[rt]=0;
    }
}
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
void build(int l,int r,int rt) {
    add[rt]=0;
    if(l==r) {
        scanf("%lld",&sum[rt]);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt);
}
void update(int a,int b,ll c,int l,int r,int rt){
    if(a<=l&&b>=r) {
        sum[rt]+=(r-l+1)*c;
        add[rt]+=c;
        return;
    }
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    if(a<=mid)    update(a,b,c,lson);
    if(b>mid)    update(a,b,c,rson);
    push_up(rt);
}
ll query(int a,int b,int l,int r,int rt) {
    if(a<=l&&b>=r)    return sum[rt];
    push_down(rt,r-l+1);
    int mid=(l+r)>>1;
    ll ans=0;
    if(a<=mid)    ans+=query(a,b,lson);
    if(b>mid)    ans+=query(a,b,rson);
    return ans;
}
int main() {
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,n,1);
    while(m--) {
        char ch;
        int a,b;    ll c;
        scanf(" %c",&ch);
        if(ch=='C') {
            scanf("%d%d%lld",&a,&b,&c);
            update(a,b,c,1,n,1);
        }
        else {
            scanf("%d%d",&a,&b);
            printf("%lld\n",query(a,b,1,n,1));
        }
    }
}