1. 程式人生 > >[HNOI2010]彈飛綿羊(分塊)

[HNOI2010]彈飛綿羊(分塊)

%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 (int
i=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]彈飛綿羊(分塊)