Useful  Skills

without algorithm & Datastrucure



Binary Search

二分搜索

當搜索的對象有單調性


對於一個問題 跟 一個序列

有這樣的性質時
Yes Yes Yes Yes No No No No No No No

就可以二分

How to?




找中間的點
mid = ( left + right ) / 2

Case 1


Yes


Yes Yes Yes Yes Yes Yes Yes No No No No

左邊的Yes都可以丟掉
left = mid;

Case 2


No


Yes Yes Yes No No No No No No No No

右邊的No都可以丟掉
right = mid;

Final




  left   right
...Yes   Yes   Yes    No   No   No...

so...
while( right - left > 1)


while( r - l  > 1){
    int mid = (l + r)  /2;
    if(Yes)  l = mid;
    else r = mid;
}

left & right?


usually you can...

1 ~ n

left = 0;

right = n+1; 

//maybe Wrong!

What can you search?


in already sort array

find a number x


if(array[mid] > x) right = mid;

else left = mid;



數值 最大化

數值 最小化

找極端值

所有單調的都可以二分



但是...

不見得會比較好

Special Case



二分答案




HOJ p003




離散化



程式不能表達連續的狀態


所以我們用 ( left , right)
描述一個區間

在一條直線上

有 N 個區間 (N<=100,000)
問你被最多區間覆蓋的區域
有多少區間

ex
1 ~ 5
2 ~ 7
6 ~ 8
3 ~ 4


1 2 3 4 5 6 7 8

o o o o o x x x

x o o o o o o x

x x x x x o o o

x x o o x x x x

1 2 3 3 2 2 2 1

用陣列記錄被覆蓋幾次


scanf( "%d %d" , &left, &right);
for(int i=left; i<=right ; i++)
array[i] ++;

100,000個區間 * 不知道多大的Range
=
TLE 

1. 加入區間跟拔除區間


scanf("%d %d", &left ,&right);

array[ left ] ++;
array[ right+1 ] --;

int  sum = 0;
for(int i=0 ; i<=N ; i++)
sum += array[i];

Sort Event


int  t[100010];
int  v[100010];
int  pos[100010];
bool  comp(int a,int b){
      return  t[a] < t[b];
}

Sort Event


for(int i=1;i<=N;i++)
     pos[i] = i;
sort(pos+1, pos+N+1, comp);

Sort Event


int sum = 0;
for(int i=1;i<=N;i++)
       sum += v[pos[i]];



Max Range : M

Max 區間數 : N


Array法  O(M)

Sort法 O(N log N)




離散化編號

Structure


struct   RILAK {
       int   i, no;
       int   v;
}array[100];

Sort COMP


bool comp1(RILAK a, RILAK b){
     return  a.v < b.v;
}
//sort

Sort COMP


bool comp2(RILAK a, RILAK b)
{
     return  a.no < b.no;
}
//sort

Sort COMP


for(int i=1;i<=N;i++)
{
     array[i].no = i;
}

Sort COMP


sort(array+1, array+N+1, comp1);
for(int i=1;i<=N;i++)
       array[i].i = i;
sort(array+1, array+N+1, comp2);




Why?




get Rank!!!

for 區間資料結構




Thx

Made with Slides.com