Hnoi2010 Bounce 彈飛綿羊

2021-07-14 05:41:18 字數 1251 閱讀 5166

從左到右有n個位置,在第i個位置會被彈到第i+a[i]個位置,超出範圍則掛掉,有q個操作,一種是更改某一位置上的a[i],一種是詢問第i個位置什麼時候會掛掉

設f(i)為i在其塊內最少跳多少次會跳出這個塊,而g(i)表示他跳出塊後會跳到哪個點,於是修改時我們可以重構塊,詢問時就乙個乙個塊跳。時間複雜度o(

nn√)

很容易發現,如果我們把跳出去都記為跳到n+1,那麼我們就可以得到一棵樹,修改操作就是刪掉一條邊,增加一條新邊,詢問就是詢問點的深度,所以我們可以用lct完美解決了!!!時間複雜度o(

nlog

2n)

我打了lct啊!!

#include

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

using

namespace

std;

typedef

long

long ll;

typedef

double db;

const

int n = 200010;

int fa[n];

struct pointtree[n];

int n,m;

int a[n];

int op[n],k,se[n];

void change(int x)

int pd(int x)

void rotate(int x)

void down(int x)

}void clear(int x)

op[++k]=x;

fd(i,k,1)down(op[i]);

}void splay(int x)

rotate(x);

}}void access(int x)

fo(i,2,k)

}void makeroot(int x)

int main()

fo(i,1,n)fa[i]=min(i+a[i],n+1);

scanf("%d",&m);

fo(i,1,m)

if (ty==2)

}fclose(stdin);

fclose(stdout);

return

0;}

HNOI2010 彈飛綿羊 bounce

標籤 分塊。題解 200000,而且標號從0開始,很符合分塊的條件啊。看看怎麼實現。首先分成 n個區間,然後如果我們對於每乙個位置i,求出乙個next i 和step i 分別表示跳到的後乙個位置與步數,因為是分塊所以就是跳到下乙個區間的步數與位置了。處理這兩個陣列要從前到後,只需要o n 然後查詢...

Bounce 彈飛綿羊

bounce 彈飛綿羊 分塊 將整個大區間分成若干塊,每個點維護到下乙個塊需要跳的次數以及會跳到哪個點 分塊要注意細節,區間開閉容易弄亂 如下 1 include2 include3 include4 include5 define b int sqrt n 6 define n 200000 7u...

hnoi2010 彈飛綿羊

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