HNOI2010 彈飛綿羊 bounce

2022-05-01 15:15:13 字數 1723 閱讀 3645

標籤:分塊。

題解:200000,而且標號從0開始,很符合分塊的條件啊。看看怎麼實現。

首先分成√n個區間,然後如果我們對於每乙個位置i,求出乙個next[i]和step[i],分別表示跳到的後乙個位置與步數,因為是分塊所以就是跳到下乙個區間的步數與位置了。處理這兩個陣列要從前到後,只需要o(n)。

然後查詢:自然是使用這兩個陣列,跳出去就return,複雜度o(√n)。

修改:修改乙個點自然是o(1),但是前面的會跳到這個地方,那不是前面的都要改?非也,因為next僅僅跨越了乙個區間,所有最多有這個區間的起始位置到i個是需要更改的,也就是最大√n個,我們從i到起始位置煩著列舉,複雜度o(√n)。

所以總的複雜度為o(m√n)。

1 #include2 #include3 #include4 #include5

using

namespace

std;

6const

int maxn=210000;7

intn,m,cnt;

8int

w[maxn],next[maxn],step[maxn],team[maxn];

9 inline int gi()

10void update(int

p)11

18int net=p+w[p];

19if(team[p]==team[net])

2024

else

2529}30

int query(int

p)31

38return

res;39}

40int

main()

4160

else

61 printf("

%d\n

",query(p));62}

63return0;

64 }

標籤:lct

題解:此題當然不缺乏lct做法,對於lct來說,這道題就是一道模板題,每次修改cut再link,維護sz代表子樹的大小。使用乙個根節點:n+1,也就是跳出去。m+a+s,查詢x的左子樹大小即可,也就是比他深度小的點的個數,不就是多少步跳出去嗎?

1 #include2 #include3 #include4

using

namespace

std;

5const

int maxn=300099;6

intn,m;

7int fa[maxn],rev[maxn],val[maxn],q[maxn],ch[maxn][2

],sz[maxn];

8bool isroot(int x)

9void update(int x)

10bool

get(int x)

11void down(int x) }

12void rotate(int

x)13

20void splay(int

x)2130}

31void access(int x) }

32void makeroot(int x)

33void link(int x,int y)

34void cut(int x,int y)

35int

main( )

3650

else

5158}59

return0;

60 }

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即可。其實我做這道題是為了找找寫動態樹的感覺,發現了不少要注意的細節。總結地說,越是基本的函式就越不能打錯,不然就要花好多的時間去查...

HNOI2010彈飛綿羊

話說我是冒著巨大的風險a這道題的 xc說不讓上其他oj 這題其實很簡單,每個點如果他能往後跳,那就只能跳到唯一的乙個,這顯然是跟森林,用lct就好,維護下size。突然變短 include include define fo i,a,b for int i a i b i define lc c x...