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, ...
随机推荐
- PS之火焰铁锈字
效果图 素材一:将下图在PS中打开,选择菜单:编辑>定义图案,命名后关闭图案 素材二 1.新建如下画布 2.将素材二拖入新建好的画布(使用移动工具) 3.先将文字图层复制4次(ctrl+J)并且 ...
- android Activity 生命周期
今天第一次详细学习android,主要了解了一下activity的生命周期,下面详细说一下自己的简介: 在Actity中最主要的有一下几个方法: protectedvoid onCreate(Bund ...
- HTML基础(2) 格式标签 文本标签
格式标签: 1.<p></p> 用来显示段落 2.<br> 控制换行 3.<nobr> </nobr> 防止浏览器将过长内容自动换行显示 ...
- 利用case when 减少表扫描次数
数据库环境:SQL SERVER 2008R2 有网友希望有人帮他优化一下他的SQL,SQL语句如下: WITH T AS ( SELECT B.O_Money MON,B.O_States STAT ...
- js操作数据库实现注册和登陆
自从node-js出现之后,不只是java,php等后端语言可以操作数据库,进行内容的增删改查,javascript简本语言同样具备了该项技能,而且在node下,js具备了很强的操作性和代码的阅读性, ...
- 283. Move Zeroes(C++)
283. Move Zeroes Given an array nums, write a function to move all 0's to the end of it while mainta ...
- socket+网路编程
1.网络编程: 通过某种计算机语言来实现不同设备间的资源共享和信息传递.计算机网络的创造可能比计算机本身意义更重大!!!(否则,你只能玩单机版游戏 OSI模型 OSI模型定义了不同计算机互联的标准,是 ...
- Ubuntu启动错误Checking Battery State的处理
一.问题描述 二.处理方法 方法一: 按下 ctrl + alt + F1,进入终端,使用管理员权限执行下列代码 sudo rm /etc/X11/xorg.conf sudo reboot 方法二: ...
- net Core 通过 Ef Core 访问、管理Mysql
net Core 通过 Ef Core 访问.管理Mysql 本文地址:http://www.cnblogs.com/likeli/p/5910524.html 环境 dotnet Core版本:1. ...
- url、base64 编码规则
UrlEncode 相关: URI所允许的字符分作保留与未保留. 保留字符是那些具有特殊含义的字符. 例如, 斜线字符用于URL (或者更一般的, URI)不同部分的分界符. 未保留字符没有这些特殊含 ...