【洛谷P1903】数颜色
题目大意:给定一个长度为 N 的序列,每个点有一个颜色。现给出 M 个操作,支持单点修改颜色和询问区间颜色数两个操作。
题解:学会了序列带修改的莫队。
莫队本身是不支持修改的。带修该莫队的本质也是对询问进行分块,不过在莫队转移时需要多维护一个时间维度,即:每个操作的相对顺序。具体来讲,将序列分成 \(O(n^{1 \over 3})\) 块,每个块的大小是 \(O(n^{2 \over 3})\),对询问的排序的优先级顺序是:询问左端点所在块,询问右端点所在块,询问的时间顺序。经过分析,带修该莫队的时间复杂度为 \(O(n^{5 \over 3})\),具体分析方式和静态莫队类似。对排好序的询问进行按顺序处理,首先考虑时间维度,通过比较时间的先后,决定是顺序执行还是时间倒流,这可以通过记录一个 pre 变量来维护。
注意:在莫队中,对于 l 的初始化应该为 1,r 的初始化应该为 0,这是由询问转移的性质决定的。对于带修改莫队来说,时间维度也需要维护一个变量,表示当前的时间。时间的初始化应该为 0。
代码如下
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define cls(a,b) memset(a,b,sizeof(a))
#define debug(x) printf("x = %d\n",x)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=5e4+10;
const int maxm=1e6+10;
const double eps=1e-6;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll sqr(ll x){return x*x;}
inline ll read(){
ll x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
/*--------------------------------------------------------*/
char s[4];
int n,m,l=1,r=0,cur=0,a[maxn],cnt[maxm],sum,ans[maxn];
struct query{int id,l,r,t,bl,br;}q[maxn];
struct node{int pos,val,pre,t;}mo[maxn];
int tot,tot1,tot2;
inline int get(int pos){return (pos-1)/tot+1;}
bool cmp(const query &x,const query &y){
return x.bl!=y.bl?x.bl<y.bl:x.br!=y.br?x.br<y.br:x.t<y.t;
}
void read_and_parse(){
n=read(),m=read(),tot=pow(n,0.6);
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='Q')++tot1,q[tot1].id=tot1,q[tot1].t=i,q[tot1].l=read(),q[tot1].r=read(),q[tot1].bl=get(q[tot1].l),q[tot1].br=get(q[tot1].r);
else ++tot2,mo[tot2].t=i,mo[tot2].pos=read(),mo[tot2].val=read();
}
sort(q+1,q+tot1+1,cmp);
}
inline void update(int x,int f){
if(f==1){
if(!cnt[a[x]])++sum;
++cnt[a[x]];
}else{
--cnt[a[x]];
if(!cnt[a[x]])--sum;
}
}
void update2(int x,int f){
if(mo[x].pos>=l&&mo[x].pos<=r){
--cnt[a[mo[x].pos]];
if(!cnt[a[mo[x].pos]])--sum;
}
if(f==1)mo[x].pre=a[mo[x].pos],a[mo[x].pos]=mo[x].val;
else a[mo[x].pos]=mo[x].pre;
if(mo[x].pos>=l&&mo[x].pos<=r){
if(!cnt[a[mo[x].pos]])++sum;
++cnt[a[mo[x].pos]];
}
}
void change(int now){
while(cur<tot2&&mo[cur+1].t<=now)update2(++cur,1);
while(cur&&mo[cur].t>now)update2(cur--,-1);
}
void solve(){
for(int i=1;i<=tot1;i++){
change(q[i].t);
while(r<q[i].r)update(++r,1);
while(r>q[i].r)update(r--,-1);
while(l>q[i].l)update(--l,1);
while(l<q[i].l)update(l++,-1);
ans[q[i].id]=sum;
}
for(int i=1;i<=tot1;i++)printf("%d\n",ans[i]);
}
int main(){
read_and_parse();
solve();
return 0;
}
【洛谷P1903】数颜色的更多相关文章
- Bzoj2120/洛谷P1903 数颜色(莫队)
题面 Bzoj 洛谷 题解 考虑对操作离线后分块处理询问操作(莫队算法),将询问操作按照编号分块后左端点第一关键字,右端点第二关键字排序(分块大小为\(n^{\frac 23}\)),对于每一个询问操 ...
- [bzoj2120] [洛谷P1903] 数颜色
Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...
- 洛谷P1903 数颜色 [国家集训队] 莫队
正解:带修莫队 解题报告: 可以理解为引入时间参数,然后就是有了仨参数,关于这个修改同样的是,如果时间是相同的,不用搞,如果时间不相同做一下时光倒流/时光推移就成嘛 但是肯定既然这样的话,按照原来的s ...
- 2018.07.07 洛谷 P3939 数颜色(主席树)
P3939 数颜色 题目背景 大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg 题目描述 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不 ...
- 洛谷——P3939 数颜色(暴力vecotr+二分)
P3939 数颜色 $vecotr$里二分就是好用,全是$STL$ 颜色数目比较少,可以对每一种颜色弄一个$vector$记录一下,查找$l,r$内颜色数为$x$的兔子数,直接在$G[x]$这个$ve ...
- 洛谷P3939 数颜色 二分查找
正解:二分 解题报告: 传送门! 话说其实我开始看到这题想到的是分块,,, 但是显然不用这么复杂,,,因为仔细看下这题,会发现每次只改变相邻的兔子的位置 所以开个vector(或者开个数组也成QwQ( ...
- 洛谷P3939 数颜色(二分 vector)
题意 题目链接 Sol 直接拿vector维护每种颜色的出现位置,然后二分一下. #include<bits/stdc++.h> using namespace std; const in ...
- [洛谷P3939]数颜色
题目大意:有n个物品,每个物品有一个颜色.现在有两种操作:1.查询l-r内有多少颜色为c的物品并输出.2.将第x个物品和第x+1个交换.现在让你实现这些操作. 解题思路:首先一共有300000种颜色, ...
- [洛谷P3939]:数颜色(二分)
题目传送门 题目描述 小$C$的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不同的兔子可能有相同的颜色.小$C$把她标号从$1$到$n$的$n$只兔子排成长长的一排,来给他们喂胡萝卜吃.排列 ...
- BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]
BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...
随机推荐
- Web移动端---iPhone X适配(底部栏黑横线)
一.相信大家有被iPhone X底部黑色横线支配的恐惧 上面我们可以看到,底部的导航栏被一条黑色横线所盖住,那么就很烦.下面我们可以开始进行适配环节 1.首先我们可以用 JS 判断手机环境是不是 iP ...
- 微信小程序自定义组件
要做自定义组件,我们先定一个小目标,比如说我们在小程序中实现一下 WEUI 中的弹窗组件,基本效果图如下. Step1 我们初始化一个小程序(本示例基础版本库为 1.7 ),删掉里面的示例代码,并新建 ...
- spring boot session error
Error starting ApplicationContext. To display the conditions report re-run your application with 'de ...
- 解析$(this).data('type');
html: <button type="button" class="layui-btn layui-btn-sm" data-type="ad ...
- do not track
privacy.trackingprotection.enabled
- Nginx 网络事件
L27-29 应用层(如浏览器等一系列组成的发送get请求) 传输层 系统内核打开一个端口将客户端IP及端口和服务端IP及端口记录下来一并传输到网络层 网络层 打包后到链路层 再到客户端路由器至广域网
- chrome实用快捷键速记
标签页和窗口快捷键 操作 快捷键 打开新窗口 Ctrl + n 无痕模式下打开新窗口 Ctrl + Shift + n 打开新的标签页,并跳转到该标签页 Ctrl + t 重新打开最后关闭的标签页,并 ...
- nginx压测工具--wrk
基本使用 命令行敲下wrk,可以看到使用帮助 Usage: wrk <options> <url> Options: -c, --connections <N> C ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- 学习Android过程中遇到的未解决问题(个人笔记,细节补充,随时更新)
201811/13 使用HttpURLConnection对象调用方法又出现IO异常,我又百度个博客搜寻答案,未果.下午试试真机,完美.自己建了服务器tomcat,编写android访问自己tomca ...