BZOJ2453:维护队列——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2453
Description
Input
Output
Sample Input
1 2
Q 1 2
R 1 2
Q 1 2
Sample Output
1
HINT
对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。
——————————————————————————————————————
一种单点修改的分块。
我们维护:
1.sum[i][j]:前j块i元素出现次数。
2.ans[i][j]:i~j块的颜色种数。
修改的时候我们显然sum数组可以O(sqrtN)修改成功,而ans数组通过暴力也可以在O(N/4)的复杂度中修改成功。
(实现方法看代码吧……)
剩下的查询就比较简单了(可能是分块分多的错觉)
#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=;
const int SQRTN=;
const int M=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct question{
char op[];
int l,r;
}q[N];
int n,m,lim,s,cnt,a[N],b[M],bl[SQRTN],br[SQRTN];
int sum[M][SQRTN],ans[SQRTN][SQRTN];
bool vis[M];
inline void initLSH(){
sort(b+,b+lim+);
lim=unique(b+,b+lim+)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+lim+,a[i])-b;
}
return;
}
inline int LSH(int x){return lower_bound(b+,b+lim+,x)-b;}
inline void intoblock(){
for(int i=;i<=n;i++){
if(i%s==){br[cnt]=i-;bl[++cnt]=i;}
}
br[cnt]=n;bl[cnt+]=n+;
return;
}
inline void init(){
for(int i=;i<=cnt;i++){
for(int j=;j<=lim;j++)sum[j][i]=sum[j][i-];
for(int j=bl[i];j<=br[i];j++){
sum[a[j]][i]++;
}
}
for(int i=;i<=cnt;i++){
for(int j=i;j<=cnt;j++){
ans[i][j]=ans[i][j-];
for(int k=bl[j];k<=br[j];k++)vis[a[k]]=;
for(int k=bl[j];k<=br[j];k++){
int t=a[k];
if(!vis[t]){
int c=sum[t][j-]-sum[t][i-];
if(!c)ans[i][j]++;
vis[t]=;
}
}
}
}
return;
}
inline void modify(int x,int c){
if(a[x]==c)return;
int now=(x-)/s+;
int old=a[x];
a[x]=c;
int nw=a[x];
for(int i=;i<=now;i++){
for(int j=now;j<=cnt;j++){
if(sum[old][j]-sum[old][i-]==)ans[i][j]--;
if(sum[nw][j]-sum[nw][i-]==)ans[i][j]++;
}
}
for(int i=now;i<=cnt;i++)sum[old][i]--,sum[nw][i]++;
return;
}
inline int query(int l,int r){
int cur=;
if(r-l+<=*s){
for(int i=l;i<=r;i++)vis[a[i]]=;
for(int i=l;i<=r;i++){
int t=a[i];
if(!vis[t]){
cur++;
vis[t]=;
}
}
return cur;
}
int L=(l-)/s+,R=(r-)/s+;
cur+=ans[L+][R-];
for(int i=l;i<=br[L];i++)vis[a[i]]=;
for(int i=bl[R];i<=r;i++)vis[a[i]]=;
for(int i=l;i<=br[L];i++){
if(!vis[a[i]]){
int c=sum[a[i]][R-]-sum[a[i]][L];
if(!c)cur++;
vis[a[i]]=;
}
}
for(int i=bl[R];i<=r;i++){
if(!vis[a[i]]){
int c=sum[a[i]][R-]-sum[a[i]][L];
if(!c)cur++;
vis[a[i]]=;
}
}
return cur;
}
int main(){
n=read();m=read();s=sqrt(n);
for(int i=;i<=n;i++)a[i]=b[++lim]=read();
for(int i=;i<=m;i++){
cin>>q[i].op;
q[i].l=read(),q[i].r=read();
if(q[i].op[]=='R')b[++lim]=q[i].r;
}
initLSH();
intoblock();
init();
for(int i=;i<=m;i++){
if(q[i].op[]=='R')modify(q[i].l,LSH(q[i].r));
else printf("%d\n",query(q[i].l,q[i].r));
}
return ;
}
BZOJ2453:维护队列——题解的更多相关文章
- BZOJ2453: 维护队列
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 183 Solved: 89[Submit][Status] Descripti ...
- [bzoj2453]维护队列_带修改莫队
维护队列 bzoj-2453 题目大意:给定一个n个数序列,支持查询区间数的种类数,单点修改.不强制在线. 注释:$1\le n,m\le 10^5$. 想法: 带修改莫队裸题. 如果没有修改操作的话 ...
- [BZOJ2453]维护队列|分块
Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会 ...
- BZOJ2453维护队列&&BZOJ2120数颜色
2016-05-28 11:20:22 共同的思路: 维护某种颜色上一次在哪里出现pre,可以知道当pre<询问的l时更新答案 块内按照pre排序 修改的时候重新O(n)扫一遍,如果和之前的不一 ...
- bzoj2120: 数颜色 &&bzoj2453: 维护队列
题目大意: 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好 ...
- 【分块】bzoj2453 维护队列
http://www.cnblogs.com/autsky-jadek/p/4020296.html 同bzoj2120. #include<cstdio> #include<cma ...
- [BZOJ2120] 数颜色 && [bzoj2453] 维护队列(莫队 || 分块)
传送门 只有第一个,第二个权限题. 分块,然而wa,没看出来错在哪里,有时间再看. #include <cmath> #include <cstdio> #include &l ...
- 【BZOJ2453】维护队列/【BZOJ2120】数颜色 分块
[BZOJ2453]维护队列 Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色 ...
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 653 Solved: 283[Submit][Status][Discuss] ...
随机推荐
- C# 浮点转时间
想了大半天实在想不出什么更适合文章的标题... 就现在这个标题,挺好- - 什么是浮点转时间呢? 今天写的一个计时功能,想来想去还是现在这种解决方案比较合适 先上一张图在来讲解比较明了 如图:赛车游戏 ...
- yield学习
如果要控制内存占用,最好不要用list来保存中间结果,而是通过iterable对象(range, xrange, generator等)来迭代. yield 使函数变为generator,返回对象 ...
- 【Extremely Basic Words for Listening】word list
[Extremely Basic Words for Listening]word list updated continuously recite count: 0 careless exercis ...
- Java开发工程师(Web方向) - 04.Spring框架 - 期末测试
Spring框架客观题 Spring框架编程题 http://blog.csdn.net/sinoacc/article/details/51702458 1 (25分) 假设有如下数据表: crea ...
- vuex-Actions的用法
Action 类似于 mutation,不同在于: Action 提交的是 mutation,而不是直接变更状态. Action 是异步的,mutation是同步的. 沿用vuex学习---简介的案例 ...
- Python3获取新浪微博内容乱码问题
用python获取新浪微博最近发布内容的时候调用 public_timeline()函数的返回值是个jsonDict对象,首先需要将该对象通过json.dumps函数转换成字符串,然后对该字符串用GB ...
- LeetCode 386——字典序排数
1. 题目 2. 解答 2.1 方法一 假设返回 118 以内数的字典顺序,则为 1,10,100,101,102,...,109,11,110,111,112,...,118,12,13,....根 ...
- Python变量常量及注释
一.变量命名规则1.有字母.数字.下划线搭配组合而成2.不能以数字开头,更不能全为数字3.不能用Python的关键字4.不要太长5.名字要有意义6.不要用中文7.区分大小写8.采用驼峰体命名(多个单词 ...
- c# 批量处理数据录入
c# 分批处理数据录入 //using System.Text; //using System.Data; //using System.Data.SqlClient; //using System; ...
- HTML5文档的各个组成部分分类
<!DOCTYPE html><!--声明文档结构类型--> <html lang="zh-cn"><!--声明文档文字区域--> ...