1. 程式人生 > >POJ 2528 Mayor's posters (線段樹 離散化+區間更新+區間求值 )

POJ 2528 Mayor's posters (線段樹 離散化+區間更新+區間求值 )

href eof 求值 給定 一個點 一個 stream 問題 void

題目鏈接:http://poj.org/problem?id=2528

題意:塗色問題,給定n個要塗色的區間(每次用的顏色不一樣,顏色覆蓋性極強),問最後能看到多少種顏色。(貼海報問題轉換)

題解:TLE+MLE(o(╥﹏╥)o),TLE線段樹解決,MLE離散化解決

離散化:[1,4],[2,6],[8,10],[3,4],[7,10] 離散化得 1,2,3,4,6,7,8,10

1 2 3 4 5 6 7 8

1 2 3 4 6 7 8 10

新的區間[1,4] [2,5] [7,8] [3,4] [6,8]

原來的要10個空間,現在離散化只要8個空間,時間復雜度驟減(離散化個人感覺就是去重,排序一下)

這道題目還要考慮一個點其實表示的是一個單位長度,所以我們可以在相鄰兩個點之間加個數,以體現這個長度

線段樹:Lazy標記,向下更新時更新完下面的節點,該節點直接塗上-1的顏色,使得查詢的時候盡可能往下查詢

挺好玩的一道題目

 1 //POJ 2528 Mayor‘s posters 
 2 //離散化  區間更新 區間求值 
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8
using namespace std; 9 10 const int N=40000+10; 11 int X[4*N],tree[4*N]; 12 int li[N],ri[N]; 13 bool vis[4*N]; 14 int ans; 15 16 void pushdown(int x){ //Lazy 17 int tmp=x<<1; 18 tree[tmp]=tree[tmp+1]=tree[x]; 19 tree[x]=-1; //向下更新,更新到每個葉子 20 //使得查詢的時候查詢葉子顏色 21 } 22 23 void
update(int l,int r,int x,int y,int col,int p){ 24 if(x<=l&&y>=r){ 25 tree[p]=col; 26 return ; 27 } 28 if(tree[p]!=-1) pushdown(p); 29 int mid=(l+r)>>1; 30 int tmp=p<<1; 31 if(y<=mid) update(l,mid,x,y,col,tmp); 32 else if(x>mid) update(mid+1,r,x,y,col,tmp+1); 33 else{ 34 update(l,mid,x,mid,col,tmp); 35 update(mid+1,r,mid+1,y,col,tmp+1); 36 } 37 } 38 39 void query(int l,int r,int x){ 40 if(tree[x]!=-1){ 41 if(!vis[tree[x]]){ 42 ans++; 43 vis[tree[x]]=1; 44 } 45 return ; 46 } 47 if(l==r) return ; 48 int mid=(l+r)>>1; 49 int tmp=x<<1; 50 query(l,mid,tmp); 51 query(mid+1,r,tmp+1); 52 } 53 54 int main(){ 55 int T,n; 56 scanf("%d",&T); 57 58 while(T--){ 59 memset(tree,-1,sizeof(tree)); //標記顏色 60 memset(vis,0,sizeof(vis)); 61 scanf("%d",&n); 62 int k=0; 63 for(int i=0;i<n;i++){ 64 scanf("%d %d",&li[i],&ri[i]); 65 X[k++]=li[i];X[k++]=ri[i]; 66 } 67 //離散化 68 sort(X,X+k); 69 int m=unique(X,X+k)-X; 70 int tmp=m; 71 for(int i=1;i<tmp;i++){ 72 if(X[i]>X[i-1]+1) X[m++]=X[i-1]+1; 73 } 74 sort(X,X+m); 75 for(int i=0;i<n;i++){ 76 int x=lower_bound(X,X+m,li[i])-X; 77 int y=lower_bound(X,X+m,ri[i])-X; 78 update(0,m-1,x,y,i,1); 79 } 80 ans=0; 81 query(0,m-1,1); 82 printf("%d\n",ans); 83 } 84 return 0; 85 }

POJ 2528 Mayor's posters (線段樹 離散化+區間更新+區間求值 )