某天,lostmonkey發明了一種超級彈力裝置,為了在他的綿羊朋友面前顯擺,他邀請小綿羊一起玩個遊戲。遊戲一開始,lostmonkey在地上沿著一條直線擺上n個裝置,每個裝置設定初始彈力係數ki,當綿羊達到第i個裝置時,它會往後彈ki步,達到第i+ki個裝置,若不存在第i+ki個裝置,則綿羊被彈飛。綿羊想知道當它從第i個裝置起步時,被彈幾次後會被彈飛。為了使得遊戲更有趣,lostmonkey可以修改某個彈力裝置的彈力係數,任何時候彈力係數均為正整數。
input第一行包含乙個整數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
output對於每個i=1的情況,你都要輸出乙個需要的步數,佔一行。
sample input4 1 2 1 1 31 12 1 11 1
sample output23
題解:這是乙個分塊的問題;我們可以將其分成sqrt(n)塊,如果有剩餘,使num+=1;然後分別記錄從當前塊到下乙個快所需的步數nxt[i]以及跳到下乙個快的位置id[i],如果一步不能到達下乙個塊 nxt[i]=nxt[i+a[i]]+1,id[i]=id[i+a[i]];(注: a[i]為第i 個彈跳的幅度),若能,nxt[i]=1,id[i]=i+a[i]。然後如果改變摸個位置的幅度,只需維護這個位置所在的塊即可(可以節省時間);
ac**為:
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int n=200005;
int belong[n],block,num,l[n],r[n],x[n],y[n];
int a[n],n,m;
void build()
else
} } void update(int s,int k)
else
} } int query(int s)
return res;
} int main()
if(s==2)
} } }
bzoj2002 彈飛綿羊
lct裸題 給出一棵樹,有修改及詢問,修改操作為修改乙個節點的父親,詢問乙個節點到根的點數。詢問及修改前只需access一遍即可。include include include include include include define rep i,x,y for int i x i y i de...
BZOJ2002 彈飛綿羊
這題可以用分塊暴力做,這裡給出正解lct的 對於每乙個彈射器i k相當於i的父親,大於n的全部歸到n 1上。這樣對於修改操作就像於換了個父親,我們要記錄下上一次的父親因為在splay中父親可能會改變。對於查詢操作就相當於把n 1mroot到根,因為你新增時會更新,不能確保n 1的位置。而答案就是xs...
BZOJ 2002 彈飛綿羊
一列n個數,a i 表示向後a i 個,問第k個數進行多少次向後跳躍會飛出去.i連向i a i 那麼我們建立乙個森林,i是i a i 的乙個子節點,如果i a i n,那麼i連向null.這樣對於節點k,問多少次飛出去,就是向上走多少個到null,也就是深度是多少,直接lct處理.注意 1.這裡的l...