[HNOI2010]彈飛綿羊(分塊)
阿新 • • 發佈:2019-03-17
%s .org www chang else || ans har hnoi
分塊大法好 ,刷分塊落谷訓練場,忽然看到這道題,大家都是什麽lct裸體
我只想問問lct是啥,於是決定拿分塊過這道題
先放題鏈接
[HNOI2010]彈飛綿羊(分塊)
題意很簡單就不解釋了
先把分塊分好 ,然後記錄每個位置彈過一個塊的步數,記錄每次彈出這個塊後的位置
如果要是單點修改的將塊內重構就好了
#include<bits/stdc++.h> using namespace std; const int N=2e5+6; int m,n,k,p,pos[N],size,a[N],num,outo[N],step[N]; struct node {int l,r,size,cnt; int pos; } bk[N]; int read() { int x=0,f=1;char ch=getchar(); while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) f=-1;ch=getchar();} while (ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘;ch=getchar();} return x*f; } void rebuild(int l,int r) { for (int i=r;i>=l;i--)if (i+a[i]>bk[pos[i]].r) {step[i]=1;outo[i]=i+a[i];} else {step[i]=step[i+a[i]]+1;outo[i]=outo[i+a[i]];} } void build() { size=sqrt(n);num=n/size; if (n%size) num++; for (int i=1;i<=num;i++) { bk[i].l=(i-1)*size+1; bk[i].r=i*size; } for (inti=1;i<=n;i++) pos[i]=(i-1)/size+1; rebuild(1,n); } void change(int x,int val) { a[x]=val; rebuild(bk[pos[x]].l,bk[pos[x]].r); } int query(int x) { int ans=step[x],y=outo[x]; for (int i=pos[x];i<=num&&y<=n;i++) { ans+=step[y];y=outo[y]; } return ans; } int main() { n=read(); for (int i=1;i<=n;i++) a[i]=read(); build(); m=read(); for (int i=1;i<=m;i++) { int opt,x,y; opt=read();x=read()+1; if (opt==1) {printf("%d\n",query(x));} if (opt==2) {y=read();change(x,y);} } return 0; }
[HNOI2010]彈飛綿羊(分塊)