POJ2828 Buy Tickets【线段树,逆序遍历】

 

刚开始看到题目,想用memmove偷懒,结果TLE,后来查了查,才发现用memmove也是O(n^2)的复杂度。。。

#include <stdio.h>
#include <string.h>
int seq[222222];
int main()
{
    int n,i,j,idx,posi,vali,t;
    while (~scanf("%d",&t))
    {
        memset(seq,0,sizeof(seq));
        for (i=0;i<t;i++)
        {
            scanf("%d%d",&posi,&vali);
            memmove(seq+posi+2,seq+posi+1,sizeof(int)*((i+1)-(posi+1)));
            seq[posi+1]=vali;
        }
        for (i=1;i<=t;i++)
            printf("%d ",seq[i]);
        printf("\b\n");
    }
    return 0;
}

 

在网上找了AC代码,还是没怎么看懂。

就知道是逆序遍历的,线段树结点存储的是当前区域的空位置数量。

关键是update函数中的代码看的不是很懂。

void update(int p,int l,int r,int rt){

  ...  

  if(Tree[rt<<1]>=p){

  update(p,lson);
  }else{
  p-=Tree[rt<<1];
  update(p,rson);

  }
}

=======================================

五一和老婆玩了2天,现在趁着假期结尾把这道题搞明白了。也敢把AC的status贴上了、嘿嘿

初始状态

首先是插入3 69

14结点有4个位置,

12结点有2个位置,小于3,因此放到14结点右孩子,且14结点空位置减1

到了14右孩子后,只要找到第3-2=1个位置即可,而34结点的左孩子33含有1个空位置,1>=1,所以放到33位置了。

 

插入2 33

 

★关键是这里如何处理★

插入2 51

此时14的左孩子只有1个位置,1<2,所以只能放到14的右孩子34

34的左孩子有0个位置,所以只能放在34的右孩子44上。

 

插入1 77

 

 

 

=======================================

Problem: 2828   User: qq1203456195
Memory: 4580K   Time: 1313MS
Language: C   Result: Accepted
 1 #include <stdio.h>
 2 #define lson l,m,rt<<1
 3 #define rson m+1,r,rt<<1|1
 4 #define maxn 222222
 5 int Tree[maxn<<2];
 6 int Seq[maxn],Pos[maxn],Val[maxn];
 7 int id;
 8 void build(int l,int r,int rt){
 9     int m=((l+r)>>1);
10     Tree[rt]=r-l+1;
11     if (l==r)
12         return;
13     build(lson);
14     build(rson);
15 }
16 void update(int p,int l,int r,int rt){
17     int m=(l+r)>>1;
18     Tree[rt]--;
19     if (l==r){
20         id=l;
21         return;
22     }
23     if(Tree[rt<<1]>=p){
24         update(p,lson);
25     }else{
26         p-=Tree[rt<<1];
27         update(p,rson);
28     }
29 }
30 int main(){
31     int n,i;
32     while(scanf("%d",&n)!=EOF)
33     {
34         build(1,n,1);
35         for (i=1;i<=n;i++)
36             scanf("%d%d",&Pos[i],&Val[i]);
37         for (i=n;i>=1;i--)
38         {
39             update(Pos[i]+1,1,n,1);
40             Seq[id]=Val[i];
41         }
42         printf("%d",Seq[1]);
43         for (i=2;i<=n;i++)
44             printf(" %d",Seq[i]);
45         printf("\n");
46     }
47     return 0;
48 }

 

posted @ 2012-04-29 13:35  ZH奶酪  阅读(3079)  评论(3编辑  收藏  举报