1. 程式人生 > >codves1282 約瑟夫問題 鏈表 會 T

codves1282 約瑟夫問題 鏈表 會 T

操作 找到 end 約瑟夫 bsp cstring ostream 快速 ase

codves1282 約瑟夫問題

STL LIST 鏈表 暴力模擬 但是會 T list

聽說正解是線段樹
分析一下,我們有以下兩種操作:

1. 找到剩余隊列中第K個人在數組中的位置
2. 刪除第K個人
假如我們一開始給每個人一個權值1,然後維護一個前綴和s(n)那麽,操作1就變成了找到前綴和為i的位置。當將第i個人刪除時,只需將其權值置0,維護好前綴和,這樣剩余隊列中第i’個人的實際位置就在原先第i人後面了。

我們可以把前綴和轉換為區間和,所以我們可以用線段樹進行快速操作

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4
#include <cmath> 5 #include <string> 6 #include <algorithm> 7 #include <iomanip> 8 #include <iostream> 9 #include <list> 10 using namespace std ; 11 12 int n,k ; 13 list<int> a ; 14 list<int> ::iterator it ; 15 list<int> ::iterator temp ;
16 17 int main() 18 { 19 scanf("%d%d",&n,&k) ; 20 for(int i=1;i<=n;i++) 21 a.push_back( i ) ; 22 it = a.begin() ; 23 for(int i=1;i<=n;i++) 24 { 25 for(int j=1;j<k;j++) 26 if( ++it==a.end() ) 27 it = a.begin() ;
28 temp = it ; 29 printf("%d ",*it ) ; 30 if( ++it==a.end() ) 31 it = a.begin() ; 32 a.erase(temp) ; 33 } 34 return 0 ; 35 }

codves1282 約瑟夫問題 鏈表 會 T