{
}
Online Python Compiler
Online R Compiler
Online SQL Editor
Online HTML/CSS Editor
Online Java Compiler
Online C Compiler
Online C++ Compiler
Online C# Compiler
Online JavaScript Compiler
Online Typescript Compiler
Online GoLang Compiler
Online Rust Compiler
Scala Online Compiler
Dart Online Compiler
Ruby Online Compiler
Online PHP Compiler
Online Swift Compiler
Generating Link
Generating Link
Share your code
Share code
Copy Link
Copied to clipboard
or share using
CYBER
CYBER
CYBER
CYBER
CYBER
66
%
OFF
Week
Week
Week
Week
Week
Stop copy pasting code you don't actually understand
Build the coding confidence you need to become a developer companies will fight for
Stop copy pasting code you don't actually understand
Become a PRO
Become a PRO
CYBER
CYBER
CYBER
CYBER
CYBER
66
%
OFF
Week
Week
Week
Week
Week
Stop copy pasting code you don't actually understand
Build the coding confidence you need to become a developer companies will fight for
Stop copy pasting code you don't actually understand
Become a PRO
Become a PRO
C++ Online Compiler
Learn Python App
Learn Python
main.cpp
Output
main.cpp
Share
Run
Run
/* // 這裡是原本的暴力模擬版本 (用 vector.erase),時間複雜度太高,所以被註解掉 #include <iostream> #include <vector> using namespace std; int main() { int N, M, K; cin >> N >> M >> K; vector<int> circle(N); for (int i=0;i<N;i++) circle[i] = i + 1; // 初始化圈子 [1..N] int pos = 0; for (int boom = 1; boom <= K; boom++) { pos = (pos + M - 1) % circle.size(); // 找到要淘汰的位置 //cout << "淘汰 " << circle[pos] << endl; if (boom == K) { int lucky = circle[(pos + 1) % circle.size()]; // 找到最後幸運者 cout << lucky << endl; return 0; } circle.erase(circle.begin() + pos); // 淘汰該人 (O(N)) if (pos == circle.size()) pos = 0; // 如果剛好刪到最後一個,重置 pos } } */ #include <bits/stdc++.h> // 匯入所有標準函式庫 using namespace std; // Fenwick Tree (Binary Indexed Tree) 結構 struct Fenwick { int l; // 陣列大小 (總人數) vector<int> temp; // Fenwick Tree 的內部陣列 (用來維護活著的人數) // 建構子:初始化長度 l,並建立一個長度 l+1 的陣列 (1-based) Fenwick(int l): l(l), temp(l+1,0) {} // 在位置 i 加上 val (更新 Fenwick Tree) void add(int i,int val){ for(; i<=l; i+=i&-i){ // i += i&-i 代表跳到下一個負責的節點 temp[i]+=val; // 更新節點值 } } // 查詢前 i 個元素的總和 (這裡命名為 all) int all(int i){ int s=0; for(; i>0; i-=i&-i) { // i -= i&-i 代表往上跳到父節點 s+=temp[i]; // 累加區間和 } return s; } // 找到第 k 個活著的人 (order statistic) int begin(int k){ int NotHere=0; // 當前已經確定不包含答案的區間右端點 // mask = 小於等於 l 的最大 2 的冪次 for(int mask=1<<(31-__builtin_clz(l));mask!=0;mask/=2){ int next=NotHere+mask; // 嘗試往右跳 mask if(next<=l && temp[next]<k){ // 如果這段區間的總和 < k,代表答案在更右邊 k-=temp[next]; // 扣掉這段的數量 NotHere=next; // 更新目前位置 } } return NotHere+1; // 回傳第 k 個活著的人的原始編號 } }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N,M,K; cin>>N>>M>>K; // 輸入人數 N、間隔 M、爆炸次數 K Fenwick fw(N); // 建立一個 Fenwick Tree,大小 N for(int i=1;i<=N;i++) fw.add(i,1); // 初始化:每個人都活著 (值=1) int alive=N; // 當前活著的人數 int pos=0; // 當前炸彈所在位置 (以活著的人數排名為基準,0-based) for(int boom=1; boom<=K; boom++){ // 模擬 K 次爆炸 pos=(pos+M-1)%alive; // 找到要淘汰的順位 (第 pos 個活著的人) int eliminated=fw.begin(pos+1); // 找到該順位對應的原始編號 fw.add(eliminated,-1); // 把這個人標記為淘汰 (設為 0) alive--; // 活著的人數減 1 if(boom==K){ // 如果是第 K 次爆炸 int luckyIndex=(pos%alive)+1; // 下一位 (1-based) int lucky=fw.begin(luckyIndex); // 找到幸運者的原始編號 cout<<lucky<<"\n"; // 輸出幸運者 return 0; // 結束程式 } } }
Output
Clear