BZOJ 2120 数颜色 分块+二分
来源:互联网 发布:直播吧软件下载 编辑:程序博客网 时间:2024/05/16 17:25
点击打开链接
题意:n个数,m个操作n,m<=1e4
1.查询[l,r]区间内有多少不同的数字
2.单点修改 (不超过1e3次)
如果利用线段树 单点更新时把x变成y后 不容易更新出[l,r]内不同数个数
此时用分块来做,记录每一个数它的上一个位置,不存在则记为0,判断[l,r]内不同的个数,如果a[i]第一次出现在[l,r]内,则ans++
更新次数<=1e3,则暴力更新n个数的b[i]和pre[i]即可,修改复杂度O(n)
若查询区间[l,r] 头尾两块直接判断b[i]<l是否成立,对中间每块的b[i]排序后二分,找到最后一个b[i]<v的位置即可 查询复杂度(sqrt(n)*logn)
#include <bits/stdc++.h>using namespace std;const int N=1e4+20;const int M=1e6+20;int n,m,a[N];int num,block,pos[N],l[N],r[N]; //num为分块的个数,block为每块的大小,pos[i]为i属于哪一块//l[i],r[i]分别为第i块左右边界int b[N],last[M],pre[N];//b,pre都是记录上一次出现位置 void reset(int x){int l=(x-1)*block+1,r=min(n,x*block);for(int i=l;i<=r;i++)pre[i]=b[i];sort(pre+l,pre+r+1);//查询时用到}void build(){block=int(sqrt(n)+log(2*n)/log(2));num=n/block;if(n%block) num++;for(int i=1;i<=n;i++){b[i]=last[a[i]];//bi:i上一次出现位置 last[a[i]]=i;//ai,最后一次出现位置 pos[i]=(i-1)/block+1;}for(int i=1;i<=num;i++)reset(i);} int find(int x,int v){int l=(x-1)*block+1,r=min(x*block,n); int first=l;while(l<=r){int mid=(l+r)>>1;if(pre[mid]<v) l=mid+1;else r=mid-1;}return l-first;}int ask(int l,int r){int ans=0;if(pos[l]==pos[r]){for(int i=l;i<=r;i++)if(b[i]<l)//上一次出现在l之前 ans++;}else{//第一块后最后一块 for(int i=l;i<=block*pos[l];i++)if(b[i]<l) ans++;for(int i=block*(pos[r]-1)+1;i<=r;i++)if(b[i]<l) ans++;}//中间的块 for(int i=pos[l]+1;i<pos[r];i++)ans+=find(i,l);return ans;}void change(int x,int v){for(int i=1;i<=n;i++)last[a[i]]=0;a[x]=v;for(int i=1;i<=n;i++)//修改操作不多于1e3 {int t=b[i];b[i]=last[a[i]];if(t!=b[i]) reset(pos[i]);last[a[i]]=i;}}int main(){while(cin>>n>>m){for(int i=1;i<=n;i++)scanf("%d",&a[i]);build();char op[5];int x,y;for(int i=1;i<=m;i++){scanf("%s%d%d",op,&x,&y);if(op[0]=='Q'){//[x,y]中有多少个不同的数printf("%d\n",ask(x,y));}elsechange(x,y);}}return 0;}
0 0
- BZOJ 2120 数颜色 分块+二分
- bzoj 2120: 数颜色(分块)
- 【BZOJ 2120】 数颜色 (分块,暴力)
- BZOJ 2453: 维护队列&&BZOJ 2120 数颜色 分块
- 【BZOJ 2120】 数颜色 (乱搞分块,直指暴力)
- [树状数组套权值线段树 || 分块] BZOJ 2120 数颜色 & BZOJ 2453 维护队列
- BZOJ 2120: 数颜色 && 2453: 维护队列 【带修莫队版题【也可以学黄学长分块
- [BZOJ 2906]颜色:分块
- BZOJ 2821 分块+二分
- bzoj 2120: 数颜色
- bzoj 2120: 数颜色
- bzoj 2120: 数颜色
- BZOJ 2120 数颜色
- BZOJ 2120 数颜色
- BZOJ 2120: 数颜色
- BZOJ 2120 数颜色
- bzoj2120 数颜色 分块
- BZOJ2120 数颜色 分块
- 关于HTTP上传文件报文代码片记录
- 工厂模式(懒汉式、饿汉式)
- 【Zookeeper】源码分析之服务器(三)
- 实战开发农商O2O在线交易系统—架构及数据库设计
- stanford_CS231n_learning note_Lec_02 Image Classification pipeline
- BZOJ 2120 数颜色 分块+二分
- FFMPEG音频解码浅析
- java获取当前时间的方法
- ASP.NET生成二维码
- What went wrong: Execution failed for task ':compileArmv7DebugJavaWithJavac'. 问题解决办法
- 软件维护
- redisson client 介绍及优缺点
- JVM细节
- css3 子元素平均宽度