BZOJ[2120]数颜色/BZOJ[2453]维护队列 分块
2018-01-12 14:37
357 查看
传送门ber~ber~
记录prei和前一个第i位颜色相同的是哪一个,在查询区间l~r时只需要在该区间找出pre小于l的记录就可以
求出每个点的pre后将序列分块,每块按pre从小到大排序,查询时对于完整的块二分查找,对于不完整的块暴力统计就可以
修改时重建,如果这位的pre不一样了,就重建该块
代码如下:
记录prei和前一个第i位颜色相同的是哪一个,在查询区间l~r时只需要在该区间找出pre小于l的记录就可以
求出每个点的pre后将序列分块,每块按pre从小到大排序,查询时对于完整的块二分查找,对于不完整的块暴力统计就可以
修改时重建,如果这位的pre不一样了,就重建该块
代码如下:
#include<algorithm> #include<cstring> #include<ctype.h> #include<cstdio> #include<cmath> #define N 1000050 using namespace std; inline int read(){ int x=0,f=1;char c; do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c)); do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c)); return x*f; } int n,m,x,y,Block_size,Block_num; int a ,b ,pos ,pre ,block ; char c[5]; inline void reset(int x){ if(x==block || x==1) return;///第一块和最后一块用不到,所以不用管它们 for(int i=Block_size*(x-1)+1;i<=Block_size*x;i++) b[i]=pre[i]; sort(b+Block_size*(x-1)+1,b+Block_size*x+1); } inline void Modify(int x,int k){ for(int i=1;i<=n;i++) pos[a[i]]=0;///这里用memset会被卡掉.. a[x]=k; for(int i=1;i<=n;i++){ if(pre[i]!=pos[a[i]]){ pre[i]=pos[a[i]]; reset(block[i]); } pos[a[i]]=i; } } inline int calc(int l,int r,int k){ int tmp=0,x=l; while(l<=r){ int mid=l+r>>1; if(b[mid]>=k) r=mid-1; else tmp=mid,l=mid+1; } if(!tmp) return 0; return tmp-x+1; } inline void Query(int l,int r){ int tmp=0; if(block[r]-block[l]<2){ for(int i=l;i<=r;i++) if(pre[i]<l) tmp++; printf("%d\n",tmp); return; } else{ for(int i=l;i<=block[l]*Block_size;i++) if(pre[i]<l) tmp++; for(int i=r;i>=(block[r]-1)*Block_size+1;i--) if(pre[i]<l) tmp++; for(int i=block[l]+1;i<block[r];i++) tmp+=calc((i-1)*Block_size+1,i*Block_size,l); printf("%d\n",tmp); } } int main(){ n=read();m=read(); Block_size=sqrt(n); for(int i=1;i<=n;i++){ a[i]=read(); pre[i]=pos[a[i]]; pos[a[i]]=i; block[i]=(i-1)/Block_size+1; } Block_num=block ; for(int i=1;i<Block_num;i++) reset(i); while(m--){ scanf("%s",c+1); x=read();y=read(); if(c[1]=='R') Modify(x,y); else Query(x,y); } return 0; }
相关文章推荐
- BZOJ 2120: 数颜色/BZOJ 2453: 维护队列 带修改莫队
- 【BZOJ2453】维护队列/【BZOJ2120】数颜色 分块
- 【BZOJ】2453: 维护队列【BZOJ】2120: 数颜色 二分+分块(暴力能A)
- Bzoj 2120: 数颜色 && 2453: 维护队列 莫队,分块,bitset
- [树状数组套权值线段树 || 分块] BZOJ 2120 数颜色 & BZOJ 2453 维护队列
- Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset
- BZOJ 2120: 数颜色 && 2453: 维护队列 【带修莫队版题【也可以学黄学长分块
- 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分
- BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
- BZOJ2453: 维护队列&2120: 数颜色
- bzoj2453 维护队列 & bzoj2120 数颜色 (带修改莫队)
- [BZOJ2120] 数颜色 && [bzoj2453] 维护队列(莫队 || 分块)
- BZOJ 2120: 数颜色&&2453: 维护队列【双倍经验】
- 【bzoj 2120】维护队列【bzoj 2453】数颜色 双倍经验!!!
- 【BZOJ】【2120】数颜色 & 【2453】维护队列
- 【bzoj 2120】维护队列【bzoj 2453】数颜色 双倍经验!!!
- 【BZOJ 2453|bzoj 2120】 2453: 维护队列 (分块+二分)
- BZOJ 2453: 维护队列&&BZOJ 2120 数颜色 分块
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
- BZOJ2453维护队列&&BZOJ2120数颜色