明显的数据结构题
这道题的特殊性在于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的更多相关文章

  1. BZOJ2120&&2453 数颜色&&维护队列

    2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1442 Solved: 678 [Submit][Status][Discuss ...

  2. BZOJ2120&2453数颜色——线段树套平衡树(treap)+set/带修改莫队

    题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...

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

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

  4. 【bzoj2120】 数颜色

    http://www.lydsy.com/JudgeOnline/problem.php?id=2120 (题目链接) 题意 给出一个n个数,m个询问,每次询问一个区间或修改一个数,求区间内不同的数有 ...

  5. 【BZOJ 2453|bzoj 2120】 2453: 维护队列 (分块+二分)

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

  6. Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 578  Solved: 247[Submit][Status][Discuss] ...

  7. BZOJ2120 数颜色 莫队 带修莫队

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...

  8. bzoj 2453 : 维护队列 带修莫队

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 952  Solved: 432[Submit][Status][Discuss] ...

  9. BZOJ2120数颜色(带修改莫队)

    莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...

随机推荐

  1. 在用VS2010连接oracle数据库时ORA-12504错误

    在用VS2010连接oracle数据库时,可能会出现: ORA-12504: TNS: 监听程序在 CONNECT_DATA 中未获得 SERVICE_NAME 只需在web.config文件Data ...

  2. String类比较,String类运算比较,String运算

    String类比较,String类运算比较 >>>>>>>>>>>>>>>>>>>&g ...

  3. 第三篇:web之前端之JavaScript基础

    前端之JavaScript基础   前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript ...

  4. 11.9 noip模拟试题

    NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...

  5. 2015前端各大框架比较(angular,vue,react,ant)

    前端流行框架大比拼 angular vue react ant-design angularjs angular是个MVVM的框架.针对的是MVVM这整个事.angular的最主要的场景就是单页应用, ...

  6. U3D 抛物线的方法

    本文转载:http://www.manew.com/thread-44642-1-1.html 无论是愤怒的小鸟,还是弓箭发射功能,亦或者模拟炮弹受重力影响等抛物线轨迹,都可以使用本文的方法,模拟绝对 ...

  7. Java 之 MYSQL 数据库搭建

    1.首先要去加载java的mysql驱动,将下载的mysql-connect-bin-java.jar包添加到该项目下2.然后通过 Class.forName("com.mysql.jdbc ...

  8. python中文件类的应用

    python中对文件.文件夹的操作需要涉及到os模块和shutil模块. 创建文件: 1) os.mknod("test.txt") 创建空文件 2) open("tes ...

  9. c语言学习之基础知识点介绍(一):输出语句和变量简单介绍

    本系列是为了学习ios做准备的,也能作为c语言入门的教程看看. c语言的程序结构: 1.顺序结构:自上而下依次执行. 2.分支结构:程序有选择的执行某段代码或者不执行某段代码. 3.循环结构:程序循环 ...

  10. 读书笔记之 - javascript 设计模式 - 代理模式

    代理(proxy)是一个对象,它可以用来控制对另一对象的访问.它与另外那个对象实现了同样的接口,并且会把任何方法调用传递给那个对象.另外那个对象通常称为本体.代理可以代替本体被实例化,并使其可被远程访 ...