博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ2002】[HNOI2010] 弹飞绵羊(大力分块)
阅读量:5237 次
发布时间:2019-06-14

本文共 2151 字,大约阅读时间需要 7 分钟。

大致题意:\(n\)个弹力装置,当到达第\(i\)个装置时,会被弹到第\(i+k_i\)个装置,若不存在第\(i+k_i\)个装置,就会被弹飞。有两种操作,一种操作是将\(k_x\)改为\(y\),另一种操作是询问从\(x\)出发被弹几次后会被弹飞。

考虑分块

这题可以用分块来做。

我们可以将弹力装置进行分块,对于每一块的弹力装置,可以先预处理出每个弹力元素弹出这个块之后到达的位置\(nxt_x\)以及需要的步骤\(val_x\)

对于询问操作,从询问的\(x\)出发,每一次将\(ans\)加上\(val_x\),然后将\(x\)更新为\(nxt_x\),直至\(x\)大于\(n\),由于每个块最多被经过一次,因此时间复杂度是\(O(\sqrt n)\)的。

而对于修改操作,只要修改一个块内的\(nxt\)\(val\)即可,不难发现修改也是\(O(\sqrt n)\)的。

因此总复杂度\(O(m\sqrt n)\),对于\(n≤200000,m≤100000\)的数据跑起来毫无压力。

代码

#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define LL long long#define swap(x,y) (x^=y,y^=x,x^=y)#define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)#define pc(ch) (pp_<100000?pp[pp_++]=(ch):(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=(ch)))#define N 200000#define SIZE 450 #define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)int pp_=0;char ff[100000],*A=ff,*B=ff,pp[100000];using namespace std;int n,Q,blo,a[N+5],pos[N+5],nxt[N+5],val[N+5];inline void read(int &x){ x=0;static char ch; while(!isdigit(ch=tc())); while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));}inline void write(int x){ if(x>9) write(x/10); pc(x%10+'0');}int main(){ register int i,op,x,y,limit,ans; for(read(n),blo=sqrt(n),i=1;i<=n;++i) read(a[i]),pos[i]=(i-1)/blo+1; for(i=n;i;--i)//先预处理出nxt[]和val[]数组 { if(pos[i]^pos[nxt[i]=i+a[i]]) val[i]=1;//如果直接弹出这个块,那么所需步骤为1 else val[i]=val[nxt[i]]+1,nxt[i]=nxt[nxt[i]];//否则,步骤数就是它所到达的下一个节点弹出这个块的步骤,且它弹出这个块后到达的元素就是它所到达的下一个节点弹出这个块后到达的元素 } for(read(Q);Q;--Q) { read(op),read(x),++x;//因为数据是0~n-1编号的,而我习惯于从1~n编号,因此将读入的编号x加1 if(op^2)//对于询问操作 { for(ans=0;x<=n;x=nxt[x]) ans+=val[x];//将ans加上x弹出当前块所需的步骤,并将x更新为它弹出当前块后到达的节点 write(ans),pc('\n');//输出ans } else { for(read(y),a[x]=y,limit=(pos[x]-1)*blo+1,i=pos[x]*blo;i>=limit;--i)//更新这个块中的信息 { if(pos[i]^pos[nxt[i]=i+a[i]]) val[i]=1;//和初始化的代码差不多 else val[i]=val[nxt[i]]+1,nxt[i]=nxt[nxt[i]]; } } } return fwrite(pp,1,pp_,stdout),0;}

转载于:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2002.html

你可能感兴趣的文章
Linux vi/vim
查看>>
zookeeper适用场景:分布式锁实现
查看>>
110104_LC-Display(液晶显示屏)
查看>>
node-day3
查看>>
javascript全局变量
查看>>
01、双击触发 “系统搜索” 和下拉 “通知中心”
查看>>
状态模式-State Pattern(Java实现)
查看>>
全连接神经网络(DNN)
查看>>
httpd_Vhosts文件的配置
查看>>
php学习笔记
查看>>
28 hashlib 模块 logging 模块 和 configparser模块 functools模块的偏函数partial
查看>>
pdf预览(pdf.js)
查看>>
AutoCAD中static 和 instance class的区别
查看>>
普通求素数和线性筛素数
查看>>
React Router 4.0 基本使用
查看>>
作业完成2
查看>>
javascript练习-定义子类
查看>>
newinstance()和new
查看>>
Java中的StringTokenizer类
查看>>
数组 泛型 协变(转载)
查看>>