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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM