[HNOI2010]BOUNCE 彈飛綿羊
阿新 • • 發佈:2017-05-17
eset pan cor 接下來 重建 一行 開始 sqrt 出發
#1 AC 5ms/14937kB
#2 AC 284ms/14937kB
#3 AC 5ms/14937kB
#4 AC 265ms/14937kB
#5 AC 188ms/14937kB
#6 AC 274ms/14937kB
#7 AC 158ms/14937kB
#8 AC 292ms/14937kB
#9 AC 441ms/14937kB
#10AC448ms/14937kB
題目描述
某天,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的情況,你都要輸出一個需要的步數,占一行。
輸入輸出樣例
輸入樣例#1:4 1 2 1 1 3 1 1 2 1 1 1 1輸出樣例#1:
2 3
解題思路
分塊經典例題,把這個長度為n的序列分成√n個,對於每段小區間,我們維護以下這幾個值:
s[i]---從第i個點跳出該小區間需要的步數(step)
t[i]---跳出該小區間後會到達哪個節點(to)
查詢時每次直接 step+=s[i],i=[i],復雜度不超過√n;
修改時直接賦值後把當前塊暴力重建,復雜度為√n;
總時間復雜度O(m*√n)
總空間復雜度O(n)
分點信息(鼠標移到方塊上有詳細信息)
源代碼
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5#define LL long long 6 using namespace std; 7 const int N=200200; 8 int k[N],bl[N],t[N],s[N]; 9 int blo,n,m,tot; 10 int read(){ 11 int v=0,f=1;char c=getchar(); 12 while(c>‘9‘||c<‘0‘){if(c==‘-‘)f*=-1;c=getchar();} 13 while(c<=‘9‘&&c>=‘0‘)v=v*10+c-‘0‘,c=getchar(); 14 return v*f; 15 } 16 void reset(int x){ 17 for(int i=min(n,x*blo);i>=(x-1)*blo+1;i--){ 18 int to=i+k[i]; 19 if(to>min(n,x*blo))s[i]=1,t[i]=to; 20 else { 21 s[i]=s[to]+1; 22 t[i]=t[to]; 23 } 24 } 25 } 26 int query(int x){ 27 int rtn=0; 28 while(x<=n){ 29 rtn+=s[x]; 30 x=t[x]; 31 } 32 return rtn; 33 } 34 void change(int x,int v){ 35 k[x]=v; 36 reset(bl[x]); 37 } 38 int main(){ 39 n=read();blo=sqrt(n); 40 for(int i=1;i<=n;i++){ 41 k[i]=read(); 42 bl[i]=(i-1)/blo+1; 43 } 44 tot=bl[n]; 45 for(int i=1;i<=tot;i++)reset(i); 46 m=read(); 47 while(m--){ 48 int opt,p,v; 49 opt=read(); 50 if(opt==1){ 51 p=read(); 52 printf("%d\n",query(p+1)); 53 } 54 if(opt==2){ 55 p=read();v=read(); 56 change(p+1,v); 57 } 58 } 59 return 0; 60 }
[HNOI2010]BOUNCE 彈飛綿羊