bzoj2120 2453
明显的数据结构题
这道题的特殊性在于n只有10000,修改的操作只有1000
那么就是说即便是O(n)的修改也没有太大的问题,只要常数写小一点即可
考虑到以前对同色点的处理
pre[i]表示与这个位置同色的前一个位置
对于一段区间l,r,如果区间中位置i,满足pre[i]<l则这个位置上的颜色是一种,被算一次
直接扫描显然O(n),但假如这段位置pre有序,我们就可以用二分
但是如果整体排序我们就不好确定区间的位置
因此我们考虑分块,每块内pre排序,当查询区间[l,r]时
先暴力统计l,r所在块内,在用二分统计在l,r所在块之间的块每块中符合条件的个数
这样的复杂度还是可以接受了
然后考虑修改,首先修改只会对原来颜色和修改成颜色的位置产生影响
我们只要找到原来颜色的下一个同色点位置并修改所在块,
并且找到现在颜色的下一个同色点位置并修改所在块
当然这个位置的所在块也是要修改的
var p,pre,b,a:array[..] of longint;
v:array[..] of boolean;
last:array[..] of longint;
t,n,m,size,i,x,y:longint;
ch:char; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=b[(l+r) div ];
repeat
while b[i]<x do inc(i);
while x<b[j] do dec(j);
if not(i>j) then
begin
y:=b[i];
b[i]:=b[j];
b[j]:=y;
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function find(x,y:longint):longint;
var l,r,m,f:longint;
begin
l:=(x-)*size+;
f:=l;
r:=x*size;
if r>n then r:=n;
while l<=r do
begin
m:=(l+r) shr ;
if b[m]<y then l:=m+
else r:=m-;
end;
exit(l-f);
end; function ask(l,r:longint):longint;
var i:longint;
begin
ask:=;
if p[l]=p[r] then
begin
for i:=l to r do //l,r在一个块
if pre[i]<l then inc(ask);
end
else begin //不在一个块
for i:=l to p[l]*size do
if pre[i]<l then inc(ask);
for i:=(p[r]-)*size+ to r do
if pre[i]<l then inc(ask);
for i:=p[l]+ to p[r]- do
ask:=ask+find(i,l);
end;
end; procedure build(x:longint);
var l,r,i:longint;
begin
l:=(x-)*size+;
r:=x*size;
if r>n then r:=n;
for i:=l to r do
b[i]:=pre[i]; //另开一个数组排序方便二分
sort(l,r);
end; procedure change(x,y:longint);
var i,j,k:longint;
begin
if a[x]=y then exit;
fillchar(v,sizeof(v),false);
i:=last[a[x]];
k:=pre[x];
v[p[x]]:=true;
j:=;
while i<>x do
begin
j:=i;
i:=pre[i];
end;
if j<> then
begin
pre[j]:=k;
v[p[j]]:=true; //原来颜色的下一个同色点的位置所在块要修改
end
else last[a[x]]:=pre[i]; //如果是原来颜色的最后一个位置 a[x]:=y;
i:=last[y];
if x>i then //如果是现在颜色的最后一个位置
begin
last[y]:=x;
pre[x]:=i
end
else begin
while not((pre[i]<x) and (x<i)) do i:=pre[i];
pre[x]:=pre[i]; //在现在颜色的链上上插入这个位置
v[p[i]]:=true; //现在颜色的下一个同色点所在位置要修改
pre[i]:=x;
end;
for i:= to t do
if v[i] then build(i);
end; begin
readln(n,m);
for i:= to n do
read(a[i]);
readln;
size:=trunc(sqrt(n)+ln(*n)/ln()); //因为查询的复杂度带了一个logn,所以块的大小这样合适
fillchar(last,sizeof(last),);
t:=;
for i:= to n do
begin
p[i]:=t; //每个位置所在块的编号
pre[i]:=last[a[i]];
last[a[i]]:=i;
if i mod size= then inc(t);
end;
if n mod size= then dec(t);
for i:= to t do
build(i); for i:= to m do
begin
readln(ch,x,y);
if ch='Q' then writeln(ask(x,y))
else change(x,y);
end;
end.
bzoj2120 2453的更多相关文章
- BZOJ2120&&2453 数颜色&&维护队列
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1442 Solved: 678 [Submit][Status][Discuss ...
- BZOJ2120&2453数颜色——线段树套平衡树(treap)+set/带修改莫队
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- BZOJ2453维护队列&&BZOJ2120数颜色
2016-05-28 11:20:22 共同的思路: 维护某种颜色上一次在哪里出现pre,可以知道当pre<询问的l时更新答案 块内按照pre排序 修改的时候重新O(n)扫一遍,如果和之前的不一 ...
- 【bzoj2120】 数颜色
http://www.lydsy.com/JudgeOnline/problem.php?id=2120 (题目链接) 题意 给出一个n个数,m个询问,每次询问一个区间或修改一个数,求区间内不同的数有 ...
- 【BZOJ 2453|bzoj 2120】 2453: 维护队列 (分块+二分)
2453: 维护队列 Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有 ...
- Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 578 Solved: 247[Submit][Status][Discuss] ...
- BZOJ2120 数颜色 莫队 带修莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...
- bzoj 2453 : 维护队列 带修莫队
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 952 Solved: 432[Submit][Status][Discuss] ...
- BZOJ2120数颜色(带修改莫队)
莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...
随机推荐
- 防御SQL注入的方法总结
这篇文章主要讲解了防御SQL注入的方法,介绍了什么是注入,注入的原因是什么,以及如何防御,需要的朋友可以参考下 SQL 注入是一类危害极大的攻击形式.虽然危害很大,但是防御却远远没有XSS那么困难 ...
- window 安装 Protobuf
环境安装 1:下载CMake 2:打开VS Command Prompt 3:修改工作目录到目标目录 cd C:\Path\to 4:创建编译完后 protobuf headers/libraries ...
- 学习java随笔第九篇:java异常处理
在java中的异常处理和c#中的异常处理是一样的都是用try-catch语句. 基本语法如下 try { //此处是可能出现异常的代码 } catch(Exception e) { //此处是如果发生 ...
- myeclipse10 中修改html,servlet,jsp等的生成模板
1.进入myeclipse的安装目录 2.用减压软件,(如winrar)打开common\plugins\com.genuitec.eclipse.wizards_9.0.0.me2011080913 ...
- C++专题 - 修练8年C++面向对象程序设计之体会 林锐
六年前,我刚热恋“面向对象”(Object-Oriented)时,一口气记住了近十个定义.六年后,我从几十万行程序中滚爬出来准备写点心得体会时, 却无法解释什么是“面向对象”,就象说不清楚什么是数学那 ...
- js实现文件上传,删除效果
效果图: 刚开始: 点击按钮"选择更多后",可以添加很多选择文件: 点击按钮"删除"后: 实现代码: <!DOCTYPE html><html ...
- 理解Javascript__undefined和null
在 ECMAScript 的原始类型中,是有Undefined 和 Null 类型的. 这两种类型都分别对应了属于自己的唯一专用值,即undefined 和 null. alert(undefined ...
- PHP 单一入口
单一入口概述 单一入口的应用程序就是说用一个文件处理所有的HTTP请求,例如不管是列表页还是文章页,都是从浏览器访问index.php文件,这个文件就是这个应用程序的单一入口. 打个比方,大家都要上W ...
- ajax只是一个称呼
记得刚入行的时候,看到ajax,即异步的javascript和xml这样一个概念,一点感觉都没有.参加工作前的第一轮面试,被问到有没有自己实现过ajax,我觉得自己实现肯定很复杂吧. 从名字理解 从名 ...
- CSS3美化表单 移动端可用
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...