1. 程式人生 > >BZOJ 1510: Kra-The Disks

BZOJ 1510: Kra-The Disks

pre clas text open iostream ios ont can term

Johnny 在生日時收到了一件特殊的禮物,這件禮物由一個奇形怪狀的管子和一些盤子組成. 這個管子是由許多不同直徑的圓筒(直徑也可以相同) 同軸連接而成. 這個管子的底部是封閉的,頂部是打開的. 下圖是由直徑為: 5cm, 6cm, 4cm, 3cm, 6cm, 2cm and 3cm 的圓筒組成的管子.
技術分享
每個圓筒的高度都是相等的, 玩具中所帶的盤子也是一些高度和它們相同的圓筒,直徑有大有小. Johnny 發明了一種遊戲,把盤子從管子頂部一個接一個的扔下去,他想知道最後這些盤子落在了哪,假設盤子落下過程中圓心和管子的軸一直保持一致,比如說我們丟下去三個盤子: 3cm, 2cm and 5cm, 下圖展示了最終它們的停止位置:
技術分享

如圖可以知道,盤子掉下去以後,要麽被某個圓筒卡住,要麽就是因為掉在了以前的一個盤子上而停住. Johnny 想知道他最後扔下去的那個盤子掉在了哪個位置,你來幫他把.
Input

第一行兩個整數 n 和 m ( 1<= n, m<= 300 000) 表示水管包含的圓筒數以及盤子總數. 第二行給出 n 個整數 r1, r2,…,rn ( 1 <=ri<= 1 000 000 000 for 1<= i<= n) 表示水管從上到下所有圓筒的直徑. 第三行給出m 個整數k1, k2,…, km ( 1<= kj<= 1 000 000 000 for 1<= j<= m) 分別表示Johnny 依次扔下去的盤子直徑.
Output

一個整數輸出最後一個盤子掉在了哪一層,如果盤子不能扔進水管,那麽打印0.
Sample Input

7 3

5 6 4 3 6 2 3

3 2 5

Sample Output

2

題解:

單調隊列

顯然,當i>j,r[i]>r[j]時r[i]可以視為r[j],對題目不會有影響

樣例就變成了5 5 4 3 3 2 2

直接單調隊列就行了,復雜度O(n+m)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using
namespace std; 6 int n,m,r[300001],tail; 7 int main() 8 {int i,j,x; 9 //freopen("kra.in","r",stdin); 10 //freopen("kra.out","w",stdout); 11 cin>>n>>m; 12 for (i=1;i<=n;i++) 13 { 14 scanf("%d",&r[i]); 15 } 16 r[0]=2e9; 17 for (i=1;i<=n;i++) 18 if (r[i]>r[i-1]) r[i]=r[i-1]; 19 tail=n; 20 for (i=1;i<=m;i++) 21 { 22 scanf("%d",&x); 23 if (tail==0) 24 { 25 cout<<0<<endl; 26 return 0; 27 } 28 while (r[tail]<x) 29 { 30 if (tail==1) 31 { 32 cout<<0<<endl; 33 return 0; 34 } 35 tail--; 36 } 37 tail--; 38 } 39 cout<<tail+1<<endl; 40 }

BZOJ 1510: Kra-The Disks