2002 HNOI2010 彈飛綿羊 LCT

2022-09-14 16:24:27 字數 1539 閱讀 7740

某天,lostmonkey發明了一種超級彈力裝置,為了在他的綿羊朋友面前顯擺,他邀請小綿羊一起玩個遊戲。遊戲一開始,lostmonkey在地上沿著一條直線擺上n個裝置,每個裝置設定初始彈力係數ki,當綿羊達到第i個裝置時,它會往後彈ki步,達到第i+ki個裝置,若不存在第i+ki個裝置,則綿羊被彈飛。綿羊想知道當它從第i個裝置起步時,被彈幾次後會被彈飛。為了使得遊戲更有趣,lostmonkey可以修改某個彈力裝置的彈力係數,任何時候彈力係數均為正整數。

第一行包含乙個整數n,表示地上有n個裝置,裝置的編號從0到n-1,接下來一行有n個正整數,依次為那n個裝置的初始彈力係數。第三行有乙個正整數m,接下來m行每行至少有兩個數i、j,若i=1,你要輸出從j出發被彈幾次後被彈飛,若i=2則還會再輸入乙個正整數k,表示第j個彈力裝置的係數被修改成k。對於20%的資料n,m<=10000,對於100%的資料n<=200000,m<=100000

對於每個i=1的情況,你都要輸出乙個需要的步數,佔一行。

4 1 2 1 1

31 1

2 1 1

1 12

3把每個點像彈到的點連邊,顯然可得出一棵樹。

而x能彈幾下顯然就是x到樹中在序列中最靠右的點的路徑的size

可是如果維護森林的話,很難知道這個splay中最大的是哪乙個

為了方便把彈飛的都連線到n+1點上,那麼x彈的次數就是x到n+1的路徑的size-1

查詢和修改操作詳見**

1 #include2 #include3 #include4

#define n (200000+100)

5using

namespace

std;

6int father[n],son[n][2

],size[n],rev[n];

7int

n,m,a[n];89

int get(int x)

10int is_root(int x)

11void update(int x)

1213

void rotate(int

x) 14

2324

void pushdown(int

x)2533}

3435

void push(int

x)36

4041

void splay(int

x)42

4849

void access(int x)

50void make_root(int x)

51int find_root(int x)

52void link(int x,int y)

53void cut(int x,int y)

54void query(int x)

55void change(int x,int y)

5657

intmain()

5867 scanf("

%d",&m);

68for (int i=1;i<=m;++i)

6974 }

BZOJ 2002 HNOI2010 彈飛羊 塊

如今,用乙隻手滑動塊,並再次改寫這個問題0.0 塊短啊 將進入春天 n片 對於每乙個彈簧的 我們記錄一下從這個彈簧出發直到彈到塊外為止的彈跳次數及落點 查詢沿著落點彈到出去為止 改動從塊開始到這個點為止改動一遍 這樣改動和查詢都是o n 的 include include include inclu...

hnoi2010 彈飛綿羊

題目描述很明確,現在的目標是均攤兩個操作的複雜度 現在我們已知有兩種方法 1.每次用o 1 的時間修改k值,用o n 的時間直接模擬回答詢問 2.每次修改了k值後用o n 的時間更新所有答案,o 1 時間回答 均攤這兩種操作,可以這樣做 由於只可以從前往後跳,所以可以把跳躍路徑壓縮,更新時把壓縮的部...

HNOI 2010 彈飛綿羊

要求維護乙個 n 個節點的森林,實現 m個詢問,其中包括 n 200,000m 100,000 動態樹的入門題。只需要實現ac cess 操作以及維護子樹大小si ze即可。其實我做這道題是為了找找寫動態樹的感覺,發現了不少要注意的細節。總結地說,越是基本的函式就越不能打錯,不然就要花好多的時間去查...