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. 04_Mybatis输入\出映射

    1. 输入映射 ​ 通过paramterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类. 1.1 传递pojo的包装对象 1.需求 ​ 完成用户信息的综合查询,需要传 ...

  2. javascript特效源码(2、图像特效)

    1.不停闪烁的图像 不停闪烁的图片[修改显示的图片及链接地址后根据说明进行共1步] 1.以下代码放在一个新建页面的HTML的<body></body> 区即可:[页面上必须什么 ...

  3. idea-----怎样取消idea默认打开工程

    怎样取消idea默认打开工程 引用:https://jingyan.baidu.com/article/656db918c05135e381249cb7.html

  4. ubuntu下apache服务器操作方法小结,具有参考借鉴价值

    这篇文章主要介绍了ubuntu下apache服务器操作方法小结,非常不错,具有参考借鉴价值,需要的朋友可以参考下(http://www.0831jl.com)Linux系统为Ubuntu 一.Star ...

  5. 「题解」:[AHOI2013]作业

    问题: 作业 时间限制: 10 Sec  内存限制: 512 MB 题面 题目描述 此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是 ...

  6. 【Uva 1220】Party at Hali-Bula

    [Link]:https://cn.vjudge.net/contest/170078#problem/M [Description] 求一个树的最大独立子集; (即树的一个点集,这个点集中任意两个点 ...

  7. Python3.6爬虫+Djiago2.0+Mysql --数据爬取

    1.下载对应版本的python mysql 模块 我的是:pymssql-2.2.0.dev0-cp36-cp36m-win_amd64.whl 2.手动创建table create table gr ...

  8. linux mysql备份shell

    #!/bin/bash # Shell script to backup MySql database # Author: Henry he # Last updated: -- # crontab ...

  9. memcache课程---3、php使用memcache缓存实例

    memcache课程---3.php使用memcache缓存实例 一.总结 一句话总结: 前置:windows下安装好memcache.exe,安装好memcache的php扩展,开启memcache ...

  10. VS2010-MFC(对话框:为控件添加消息处理函数)

    转自:http://www.jizhuomi.com/software/156.html MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理.比如我们点击 ...