poj2828 经典线段树应用 逆序插入

之前用指针存叶节点以为能少一遍遍历  结果提交上去还慢一些!


思路:一开始看到这道题觉得应该是链表 但是时间复杂度太高了(是我太嫩了 -  -)

怎么才能按要求排好序呢?答案是看题解..好吧..记住有这种用法就好了..



#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson num<<1
#define rson num<<1|1
#define gl l,(l+r)>>1,lson
#define gr ((l+r)>>1)+1,r,rson
using namespace std;
const int maxn = 200010;

struct node
{
    bool l;     ///l left
    int c,n;    ///c count, n number
}st[maxn<<3];


int lc;   /// leaf count
void build(int l,int r,int num) ///set leaf node and initialize save[]
{
    st[num].c=r-l+1;
    st[num].n=0;
    //printf("build %d:%d\n",num,st[num].c);
    if(l==r)
    {
        //puts("end");
        st[num].l=1;
        return;
    }
    st[num].l=0;
    build(gl);
    build(gr);
}

void insert(int pos,int v,int num)
{
    //printf("now %d\n",num);
    st[num].c--;
    if(st[num].l)
    {
        st[num].n=v;
        return;
    }
    if(pos<st[lson].c)
        insert(pos,v,lson);
    else
        insert(pos-st[lson].c,v,rson);
}


void dfs(int num)
{
    if(st[num].l)
    {
        if(lc++)
            printf(" ");
        printf("%d",st[num].n);
        return;
    }
    dfs(lson);
    dfs(rson);
}

int in[maxn][2];
int main()
{
    //freopen("b.in","r",stdin);
    int n,cas=0;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d%d",&in[i][0],&in[i][1]);
        lc=0;
        build(1,n,1);
        for(int i=n-1;i>=0;i--)
            insert(in[i][0],in[i][1],1);

        lc=0;
        if(cas++) puts("");
        dfs(1);
    }
    return 0;
}


你可能感兴趣的:(线段树,ACM)