從左到右有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 時間回答 均攤這兩種操作,可以這樣做 由於只可以從前往後跳,所以可以把跳躍路徑壓縮,更新時把壓縮的部...