【bzoj2453】维护队列
来源:互联网 发布:淘宝美化图片的软件 编辑:程序博客网 时间:2024/04/27 04:52
Description
你小时候玩过弹珠吗?
小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。
Input
输入文件第一行包含两个整数N和M。
第二行N个整数,表示初始队列中弹珠的颜色。
接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。
Output
对于每个Q操作,输出一行表示询问结果。
Sample Input
2 3
1 2
Q 1 2
R 1 2
Q 1 2
Sample Output
2
1
HINT
对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。
题解
用pre[i]记录前一个和i相同颜色的球的所在位置
询问l到r时,如果pre[i]< l说明在l到r这一段没有和i颜色相同的球,则ans++
然后分块
每一块内按pre[i]排序,二分即可。
代码
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#define N 10001#define M 1000001using namespace std;int n,q,m,block;int c[N],pos[N],pre[N],b[N],last[M];inline 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 reset(int x){ int l=(x-1)*block+1,r=min(x*block,n); for(int i=l;i<=r;i++)pre[i]=b[i]; sort(pre+l,pre+r+1);}void build(){ for(int i=1;i<=n;i++) { b[i]=last[c[i]]; last[c[i]]=i; pos[i]=(i-1)/block+1; } for (int i=1;i<=m;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 x,int y){ int ans=0; if (pos[x]==pos[y]) { for (int i=x;i<=y;i++)if (b[i]<x) ans++; } else { for (int i=x;i<=block*pos[x];i++)if (b[i]<x) ans++; for (int i=block*(pos[y]-1)+1;i<=y;i++)if (b[i]<x) ans++; } for (int i=pos[x]+1;i<pos[y];i++) ans+=find(i,x); return ans;}void change(int x,int v){ for(int i=1;i<=n;i++)last[c[i]]=0; c[x]=v; for(int i=1;i<=n;i++) { int t=b[i]; b[i]=last[c[i]]; if(t!=b[i])reset(pos[i]); last[c[i]]=i; }}int main(){ n=read();q=read(); for (int i=1;i<=n;i++) c[i]=read(); block=int(sqrt(n)+log(2*n)/log(2)); if(n%block)m=n/block+1; else m=n/block; build(); char ch[5];int x,y; for(int i=1;i<=q;i++) { scanf("%s",ch); x=read();y=read(); if(ch[0]=='Q')printf("%d\n",ask(x,y)); else change(x,y); } return 0;}
0 0
- 【bzoj2453】维护队列 分块
- [bzoj2453]维护队列
- bzoj2453: 维护队列
- 【bzoj2453】维护队列
- bzoj2453[维护队列]
- 【bzoj2453】 维护队列
- [BZOJ2453]维护队列(分块)
- BZOJ2453: 维护队列(分块)
- [bzoj2453]【NOI2011模拟7.23】维护队列
- BZOJ2453: 维护队列&2120: 数颜色
- BZOJ2453 维护队列 解题报告【数据结构】【分块】
- bzoj2120: 数颜色 &&bzoj2453: 维护队列
- bzoj2453&2120 维护队列 可修改莫队算法/树套树
- bzoj2453 维护队列 & bzoj2120 数颜色 (带修改莫队)
- bzoj2453
- 维护队列
- bzoj 2453: 维护队列
- bzoj 2453: 维护队列
- 计算机编程
- 编写方法,输出给定日期所在月份的第一天和最后一天
- 验证STM32是小端存储
- session_set_cookie_params()
- IIS文件上传、下载MIME类型设置和文件大小设置
- 【bzoj2453】维护队列
- JAVA中protected的作用
- 【编译原理】高级语言及其语法描述
- Matlab C混合编程配置
- 博客测试
- poj1200(字符串哈希)
- 第12期 《田家少闲月》5月刊
- vim和ctags配置(ubuntu)
- 【Java】多线程通信