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, ...
随机推荐
- Linux文件/目录权限整理
- centos 6.3 编译安装 nginx +mysql + php
这篇文章是对另一篇文章的整理,作为记录收藏 1,配置防火墙,开启80端口.3306端口 配置iptables,开启80端口.3306端口 vi /etc/sysconfig/iptables -A I ...
- in 与 = 的区别
in 与 = 的区别 结果是相同的.
- js使用
js使用 HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 <body> 和 <head&g ...
- maven中tomcat7-maven-plugin插件的使用
1.(挺清晰,但是我在项目上尝试没有成功) http://blog.csdn.net/yhhazr/article/details/7866501 2.(算是有一些详细的运行命令吧,例如自动打包命令或 ...
- Tomcat源码学习记录--web服务器初步认识
Tomcat作为开源的轻量级WEB服务器,虽然不是很适合某些大型项目,但是它开源,读其源代码可以很好的提高我们的编程功底和设计思维.Tomcat中用到了很多比较好的设计模式,其中代码风格也很值得我们去 ...
- LINUX 添加定时任务
LINUX 添加定时任务 crontab - l按 i:x 先按 esc然后 敲入 命令 :x*/5 3 * * 0 /root/ v.sh ..重启服务 service crond restart
- WinForm控件复杂数据绑定常用数据源(对Combobox,DataGridView等控件DataSource赋值的多种方法)
开始以前,先认识一下WinForm控件数据绑定的两种形式,简单数据绑定和复杂数据绑定. 1) 简单数据绑定 简单的数据绑定是将用户控件的某一个属性绑定至某一个类型实例上的某一属性.采用如下形式进行绑定 ...
- 我的接口框架---框架函数文件common.php
<?php defined('JDHU') OR die('no allow access'); /** * 加载配置文件 */ function &get_config($replac ...
- jquery插件-validate
1.引入js,css 下载地址:http://plugins.jquery.com/validate/ 2.设置验证规则:input的class添加以下验证属性 3.设置不符合规则的提示信息:添加da ...