線段樹解約瑟夫環

2021-08-28 17:46:36 字數 817 閱讀 6904

題幹:

這道題如果用迴圈鍊錶模擬,時間複雜度很不友好,o(mn),絕對超時。聽大佬們說可以用線段樹來做,用線段樹來查詢下一次要刪除的數,時間複雜度最終為o(nlogn)。

網上看了這個大佬關於線段樹的詳解:

最終ac**:

#include using namespace std;

struct node;

node *tree;

void build(int left,int right,int index)

int mid=(left+right)/2;

build(left,mid,index<<1);//構建左子樹

build(mid+1,right,index<<1|1);//構建右子樹

tree[index].num=tree[index<<1].num+tree[index<<1|1].num;

}int update(int p,int index)

tree[index].num--;

if(p<=tree[index<<1].num)//如果p<=左子節點中有效元素的個數則從左葉子節點刪除

return update(p,index<<1);

else//否則從右子節點中刪除

return update(p-tree[index<<1].num,index<<1|1);

}int main()

cout

理解 約瑟夫環

總結了個小經驗,有時候光靠看是看不出什麼端倪來的,還必須得動下筆,比劃比劃也許就那麼簡單 include include typedef struct node node node creatlist int n 建立乙個含 n個人的迴圈鍊錶 p next head 構建迴圈鍊錶 return he...

JAVA求解約瑟夫環

與前面我們介紹的大多數程式問題一樣,約瑟夫環問題也是來自於乙個故事。這個故事發生在乙個名叫約瑟夫的猶太人身上,據說在羅馬人占領喬塔帕特後,39 個猶太人與約瑟夫及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人 開始報數,每報數到第...

ural1521 線段樹解約瑟夫問題

使用sum陣列來記錄當前區段的個數 pushup來更新子節點與父節點的關係,實現很簡單,但是要注意每次節點個數在減少,注意查詢時要求的長度要模一下當前節點的個數 include include include using namespace std const int maxn 100010 int...