2453: 维护队列

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 1442 Solved: 678

[Submit][Status][Discuss]

Description

你小时候玩过弹珠吗?

小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

Input

输入文件第一行包含两个整数N和M。

第二行N个整数,表示初始队列中弹珠的颜色。

接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

Output

对于每个Q操作,输出一行表示询问结果。

Sample Input

2 3

1 2

Q 1 2

R 1 2

Q 1 2

Sample Output

2

1

HINT

对于100%的数据,有\(1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000\),小朋友A不会修改超过\(1000\)次,所有颜色均用\(1\)到\(10^6\)的整数表示。

题解

待修改的莫队,对于每个询问,开三维\(l\),\(r\),\(t\),表示询问区间\([l,r]\),在第\(t\)次操作之后。先按\(l\)所在块排序,再按\(r\)所在块排序,再按\(t\)排序即可。

执行的时候,先把修改时间定位,然后定位右端点,最后定位左端点。分块大小\(n^\frac{2}{3}\),时间复杂度\(O(n^\frac{5}{3})\)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <cmath>
#include <string>
#define abs(x) ((x) < 0 ? -1 * (x) : (x))
template <class T>
inline void read(T &x)
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9') c = ch, ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
if(c == '-') x = -x;
}
inline int max(int a, int b){return a > b ? a : b;}
inline int min(int a, int b){return a < b ? a : b;}
const int INF = 0x3f3f3f3f;
const int MAXN = 1000000 + 10;
int n,m,color[MAXN],p[MAXN],c[MAXN],last[MAXN],ctot,qtot,belong[MAXN],size;
char s[100];
struct Node
{
int l, r, t, rank;
}node[MAXN];
bool cmp(Node a, Node b)
{
return belong[a.l] == belong[b.l] ? (belong[a.r] == belong[b.r] ? a.t < b.t : belong[a.r] < belong[b.r]) : belong[a.l] < belong[b.l];
}
int l = 1, r = 0, now = 0, ans = 0, tong[MAXN], a[MAXN], pos[MAXN];
void add(int x){ans += (++ tong[x]) == 1;}
void del(int x){ans -= (-- tong[x]) == 0;}
void change(int p, int c)
{
if(l <= p && p <= r) add(c), del(color[p]);
color[p] = c;
}
int main()
{
read(n), read(m);
for(int i = 1;i <= n;++ i) read(color[i]), tong[i] = color[i];
for(int i = 1;i <= m;++ i)
{
scanf("%s", s + 1);
if(s[1] == 'Q') ++ qtot, read(node[qtot].l), read(node[qtot].r), node[qtot].t = ctot, node[qtot].rank = qtot;
else if(s[1] == 'R') ++ ctot, read(p[ctot]), read(c[ctot]), last[ctot] = tong[p[ctot]], tong[p[ctot]] = c[ctot];
}
memset(tong, 0, sizeof(tong));
int size = pow(n, 0.66667);
for(int i = 1;i <= qtot;++ i)
if((i - 1) % size == 0) pos[i] = pos[i - 1] + 1;
else pos[i] = pos[i - 1];
std::sort(node + 1, node + 1 + qtot, cmp);
for(int i = 1;i <= qtot;++ i)
{
while(now < node[i].t) ++ now, change(p[now], c[now]);
while(now > node[i].t) change(p[now], last[now]), -- now;
while(r < node[i].r) ++ r, add(color[r]);
while(r > node[i].r) del(color[r]), -- r;
while(l < node[i].l) del(color[l]), ++ l;
while(l > node[i].l) -- l, add(color[l]);
a[node[i].rank] = ans;
}
for(int i = 1;i <= qtot;++ i) printf("%d\n", a[i]);
return 0;
}

BZOJ2120&&2453 数颜色&&维护队列的更多相关文章

  1. bzoj2120 / P1903 [国家集训队]数颜色 / 维护队列(带修改莫队)

    P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队 在原有指针$(l,r)$上又添加了时间指针$t$ 贴一段dalao的解释 带修改的莫队,和原版莫队相比,多了一个时间轴 原版莫队是将区间( ...

  2. 题解 洛谷P1903/BZOJ2120【[国家集训队]数颜色 / 维护队列】

    对于不会树套树.主席树的本蒟蒻,还是老老实实的用莫队做吧.... 其实这题跟普通莫队差不了多远,无非就是有了一个时间,当我们按正常流程排完序后,按照基本的莫队来,做莫队时每次循环对于这一次操作,我们在 ...

  3. 洛谷 P1903 [国家集训队]数颜色 / 维护队列

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

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

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

  5. P1903 [国家集训队]数颜色 / 维护队列

    思路 带修莫队的板子 带修莫队只需要多维护一个时间的指针即可,记录一下每个询问在第几次修改之后,再回退或者前进几个修改操作 排序的时候如果a.l和b.l在一个块里,就看r,如果a.r和b.r在一个块里 ...

  6. P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队

    \(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...

  7. P1903 [国家集训队]数颜色 / 维护队列(带修莫队)

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

  8. 洛谷P1903 [国家集训队]数颜色 / 维护队列 ( 带 修 )

    题意:有两种操作: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col. 对每个1操作 输出答案: 带修莫队 模板题 (加 ...

  9. 洛谷 P1903 [国家集训队]数颜色 / 维护队列 带修莫队

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

随机推荐

  1. 分析Hive表和分区的统计信息(Statistics)

    类似于Oracle的分析表,Hive中也提供了分析表和分区的功能,通过自动和手动分析Hive表,将Hive表的一些统计信息存储到元数据中. 表和分区的统计信息主要包括:行数.文件数.原始数据大小.所占 ...

  2. Python版本OpenCV安装配置及简单实例

    # 2018-06-03 # 1. Python下载:https://www.python.org/downloads/ 选择对应平台对应版本的的Python进行安装. 2. Python版OpenC ...

  3. MapReduce的体系结构

  4. 关于spring java.lang.IllegalArgumentException: Name for argument type [java.lang.String] 的错误

    况描述: web工程在windows环境eclipse下编译部署没有问题,系统升级时需要运维从Git取相应的源码并编译部署到线上机器,部署启动正常没有错误,当访问业务的action时报错,如下. 错误 ...

  5. [JZOJ5232] 【NOIP2017模拟A组模拟8.5】带权排序

    题目 题目大意 有一个数列AAA,数列上的每个数都是在[li,ri][l_i,r_i][li​,ri​]范围内随机的数. 将这个数列进行稳定排序,得到每个位置在排序后的排名pip_ipi​. f(A) ...

  6. idea加载完文件报错:java:-source 1.7中不支持lambda表达式 解决方案

    1.file - Project Structure ctrl+alt+shift+s 2.modules 中把7换成8

  7. angularjs中使用swiper时不起作用,最后出现空白位

    controller.js中定义swipers指令: var moduleCtrl = angular.module('newscontroller',['infinite-scroll','ngTo ...

  8. vuex基础知识总结

    项目中要求添加vuex,根据学习我这个小白总结了一点自己的心得,供大家参考 在学习之前,要知道两件事 为什么要用vuex?vuex要什么场景下应用? 简单点解释一下 1.项目中应用了vue脚手架之后, ...

  9. js声明变量的三种方式

    JS 声明变量的三种方式 (1)使用变量步骤:a.声明-->b.赋值-->3.调用 正确用法: <script type="text/javascript"> ...

  10. 《DSP using MATLAB》Problem 7.38

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...