1. 程式人生 > >CF830B:Cards Sorting

CF830B:Cards Sorting

二分查找 play cst closed logs string pan tor mes

對疊放著的n張牌,第i張牌寫有數字Ai,進行操作:將牌堆頂的牌取出,若是當前牌堆最小值就扔掉,否則放到牌堆底,求牌堆空時操作次數。

怎麽看怎麽像約瑟夫。。不過約瑟夫DP我不太熟,於是就yy了一下

“當前最小值”??優先隊列。把Ai和i綁起來扔到優先隊列裏,就可以知道下一步要跳到哪裏。

有個問題:如果有多個Ai怎麽辦???把這些相同的數字列出來,下標升序排列,假如上一次抽完牌的位置是now,那麽它在把所有這些相同的數字取完後,會走到“離now最近的第一個比now小的下標”那裏

因此優先隊列中以數字大小為第一關鍵字而位置為第二,每次取出相同數字的所有位置,利用單調性邊取邊直接判斷我們要找的“離now最近的第一個比now小的下標”(然而代碼中我傻了,拿下標出來二分查找)

這樣統計答案還有個小問題:有些牌已經被抽掉了,所以用下標統計答案是不行滴!那就加個樹狀數組吧,復雜度O(nlog2n)

技術分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<queue>
 7 //#include<iostream>
 8 using namespace std;
 9 
10 struct heapnode
11
{ 12 int v,id; 13 bool operator < (const heapnode &b) const 14 {return v<b.v || (v==b.v && id<b.id);} 15 bool operator > (const heapnode &b) const {return b<*this;} 16 }; 17 priority_queue<heapnode,vector<heapnode>,greater<heapnode> > q;
18 int n; 19 int x; 20 #define maxn 100011 21 int list[maxn],len; 22 #define LL long long 23 int find(int x) 24 { 25 if (x<=list[1]) return 0; 26 int L=1,R=len; 27 while (L<R) 28 { 29 int mid=(L+R+1)>>1; 30 if (list[mid]>=x) R=mid-1; 31 else L=mid; 32 } 33 return L; 34 } 35 struct BIT 36 { 37 int a[maxn]; 38 int lowbit(int x) {return x&-x;} 39 int query(int x) 40 { 41 x++; 42 int ans=0; 43 for (;x;x-=lowbit(x)) ans+=a[x]; 44 return ans; 45 } 46 void add(int x,int v) 47 { 48 x++; 49 for (;x<=n;x+=lowbit(x)) a[x]+=v; 50 } 51 }t; 52 int main() 53 { 54 scanf("%d",&n); 55 for (int i=0;i<n;i++) 56 { 57 scanf("%d",&x); 58 q.push((heapnode){x,i}); 59 t.add(i,1); 60 } 61 int now=0;LL ans=1; 62 while (!q.empty()) 63 { 64 int p=q.top().v; 65 list[len=1]=q.top().id; 66 q.pop(); 67 while (!q.empty() && q.top().v==p) 68 { 69 list[++len]=q.top().id; 70 q.pop(); 71 } 72 int tmp=find(now); 73 if (!tmp) 74 { 75 ans=ans+t.query(list[len])-t.query(now); 76 now=list[len]; 77 } 78 else 79 { 80 ans=ans+t.query(list[tmp])+t.query(n-1)-t.query(now); 81 now=list[tmp]; 82 } 83 for (int i=1;i<=len;i++) t.add(list[i],-1); 84 } 85 printf("%I64d\n",ans); 86 return 0; 87 }
View Code

CF830B:Cards Sorting