Description

你小时候玩过弹珠吗?
小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。
 
  思路很简单,在[l,r]中出现过的颜色数量
  我们设b[i]为第i位的数其之前出现的时候的下标
  只要统计在[l,r]间,b[i]<l的数量即可
  
  只要在每次修改的时候维护好b,再每次排序,询问的时候二分查找即可。
  如何维护b呢?
  对于每一个修改,它最多影响两个数的b,一个是它自身,一个是它后面遇到的第一个与它相等的数
  我们只要重新对两个块排序
  但是处理处b,刚开始我想要在每个块中再维护一个以颜色为第一关键字,下标为第二关键字的序列
  对于每个块二分找到修改的点前一次出现的位置 但是感觉十分麻烦
  看了下数据,修改的次数不会超过1000,n<=10000,每次重新算一遍b数组也是可以的
  但是第一次提交TLE了,发现习惯性的fillchar实际上时间并不那么快
  统计b的last数组实际上O(n)赋值比fillchar要快得多(因为last的范围的[0..10^6]啊/w\)
 program bzoj2453;
const maxn=;maxm=;
var n,m,i,block,x,y,q:longint;
ch:char;
pos,a,b,pre:array[-..maxn]of longint;
last:array[-..maxm]of longint; function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end; procedure qsort(L,R:longint);
var i,j,mid:longint;
begin
i:=L;j:=R;mid:=pre[random(R-L+)+L];
repeat
while (i<R)and(pre[i]<mid) do inc(i);
while (L<j)and(pre[j]>mid) do dec(j);
if i<=j then
begin
pre[]:=pre[i];pre[i]:=pre[j];pre[j]:=pre[];
inc(i);dec(j);
end;
until i>j;
if i<R then qsort(i,R);
if L<j then qsort(L,j);
end; procedure new(x:longint);
var l,r,i:longint;
begin
l:=(x-)*block+;r:=min(x*block,n);
for i:=l to r do pre[i]:=b[i];
qsort(l,r);
end; procedure change(x,y:longint);
var i:longint;
begin
for i:= to n do last[a[i]]:=;
a[x]:=y;
for i:= to n do
begin
if last[a[i]]<>b[i] then
begin b[i]:=last[a[i]];
new(pos[i]);
end;
b[i]:=last[a[i]];
last[a[i]]:=i;
end;
end; function find(x,y:longint):longint;
var L,R,mid:longint;
begin
find:=(x-)*block;
L:=find+;R:=min(x*block,n);
while L<=R do
begin
mid:=(L+R) >> ;
if pre[mid]<=y then
begin
find:=mid;L:=mid+;
end else R:=mid-;
end;
dec(find,(x-)*block);
end; procedure build;
var i:longint;
begin
for i:= to n do last[a[i]]:=;
for i:= to n do
begin
b[i]:=last[a[i]];
last[a[i]]:=i;
end;
for i:= to m do new(i);
end; function query(x,y:longint):longint;
var i,tot:longint;
begin
tot:=;
if pos[x]=pos[y] then
begin
for i:=x to y do if b[i]<=x- then inc(tot);
end else
begin
for i:=x to pos[x]*block do if b[i]<=x- then inc(tot);
for i:=(pos[y]-)*block+ to y do if b[i]<=x- then inc(tot);
for i:=pos[x]+ to pos[y]- do inc(tot,find(i,x-));
end;
exit(tot);
end; begin
readln(n,q);
block:=trunc(sqrt(n));
for i:= to n do
begin
read(a[i]);
pos[i]:=(i-) div block+;
end;
readln;
if n mod block= then m:=n div block else m:=n div block+;
build;
for i:= to q do
begin
read(ch);
if ch='Q' then
begin
readln(x,y);
writeln(query(x,y));
end else
begin
readln(x,y);
change(x,y);
end;
end;
end.

[BZOJ2453]维护队列|分块的更多相关文章

  1. BZOJ2453: 维护队列

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 183  Solved: 89[Submit][Status] Descripti ...

  2. [bzoj2453]维护队列_带修改莫队

    维护队列 bzoj-2453 题目大意:给定一个n个数序列,支持查询区间数的种类数,单点修改.不强制在线. 注释:$1\le n,m\le 10^5$. 想法: 带修改莫队裸题. 如果没有修改操作的话 ...

  3. [BZOJ2120] 数颜色 && [bzoj2453] 维护队列(莫队 || 分块)

    传送门 只有第一个,第二个权限题. 分块,然而wa,没看出来错在哪里,有时间再看. #include <cmath> #include <cstdio> #include &l ...

  4. 【bzoj2453】维护队列 (分块 + 二分)

    传送门(权限题) 题目分析 题意为:求区间内有多少种不同的数,带修改. 首先对原序列分块,用last[i]表示与i相同的上一个在哪里,然后将分块后的数组每个块内的按照last进行排序,这样查询时就可以 ...

  5. 【分块】bzoj2453 维护队列

    http://www.cnblogs.com/autsky-jadek/p/4020296.html 同bzoj2120. #include<cstdio> #include<cma ...

  6. BZOJ2453维护队列&&BZOJ2120数颜色

    2016-05-28 11:20:22 共同的思路: 维护某种颜色上一次在哪里出现pre,可以知道当pre<询问的l时更新答案 块内按照pre排序 修改的时候重新O(n)扫一遍,如果和之前的不一 ...

  7. bzoj2120: 数颜色 &&bzoj2453: 维护队列

    题目大意: 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好 ...

  8. 【BZOJ2473/2120】维护队列 分块+二分

    Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会 ...

  9. BZOJ 2453 维护队列 | 分块

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2453 题解: 考虑维护每个位置的颜色上一次出现在哪里,计为pre[i],在询问l到r的时候, ...

随机推荐

  1. 玩转Node.js(四)-搭建简单的聊天室

    玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...

  2. [B2B、B2C、C2C] 区别介绍

    最近在学习建站系统的时候,偶尔我们的老大会说几个自己所不太了解的名词“简称”,所以呢?我就总结了一下,如果有不全面的地方,还请博友们多多指点! B2B B2B(也有写成BTB)是指企业对企业之间的营销 ...

  3. Django数据模型--字段整理

    一.字段 1.CharField: 字段数据类型为字符串 2.IntegerField: 字段数据类型为整形 3.BooleanField: 布尔类型 4.NullBooleanField: 允许为空 ...

  4. 剑指offer-旋转数组的最小数字06

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...

  5. 【习题集锦】全国青少年NOIP培训教材 ISBN 978-7-305-04246-1

    目录 第一章 回溯法 找路径问题 递归代码: procedure find(k:integer); {找第K步的可能性} begin if 到目的地 {表示一条路已找出} then begin 输出路 ...

  6. Linux 简单socket实现TCP通信

    服务器端代码 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <stri ...

  7. DFS(8)——poj2034Anti-prime Sequences

    一.题目回顾 题目链接:Anti-prime Sequences Sample Input 1 10 2 1 10 3 1 10 5 40 60 7 0 0 0   Sample Output 1,3 ...

  8. Python时间获取及转换知识汇总

    时间处理是我们日常开发中最最常见的需求,例如:获取当前datetime.获取当天date.获取明天/前N天.获取当天开始和结束时间(00:00:00 23:59:59).获取两个datetime的时间 ...

  9. 关于配置tomcat多版本同eclipse的配置问题

    最近很多同学都在反应tomcat和eclipse关联的问题,其他问题网上搜索下大多都有结果,有比较疑难杂症的,下面贴出: 有的同学之前配置过tomcat6的版本或者在此之前做过配置,现在配置tomca ...

  10. Jboss6内存修改

    1.启动脚本:/home/jboss/jboss-eap-6.2/bin/standalone.sh -Djboss.bind.address.management=192.168.0.62 -Djb ...