[HNOI2010]弹飞绵羊
written on 2022-05-19
第三十篇题解 /kk
基础太烂,于是需要回顾旧知。
分块题做得不多,这道题是一个思路很清晰的分块题,于是就拿这道题回忆一下分块。
先贴一下分块模板
scanf("%d",&n);
B=sqrt(n);
num=n/B;if(n%B) num++;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
id[i]=(i-1)/B+1;
}
for(int i=1;i<=num;i++) L[i]=(i-1)*B+1,R[i]=i*B;
L[1]=1,R[num]=n;
此题的大体思路就是,对原序列进行分块,对于一个点,统计它跳出本块所需的最小次数,同时记录跳出块后落到的位置。每次修改只需更新块内的所有信息即可(正确性换段说明),查询时用一个 while 来跳即可。
正确性说明:首先后面的块肯定不用更新的,主要是前面的块。但更改的只是本块,而前一块中维护的都是为了跳出自己那块的信息,因此不涉及本块。
代码实现很简单,就不贴了。