BZOJ2120数颜色(带修改莫队)
莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下。具体思想是:如果把一个询问[l,r]看做平面上的点(l,r)的话,两个询问状态之间的转移代价可以看做这两个点的曼哈顿距离。这样我们可以通过预处理出曼哈顿最小生成树解决这类问题,但莫队算法可以直接在根号复杂度下解决。
带修改莫队实际上是普通二维莫队的基础上增加了第三维(修改时间),这样就要求我们可以在较低复杂度下在某个区间内执行一个修改操作。以(l/B,r/B,t)为关键字,可以证明转移总复杂度为$O(n^{\frac{5}{3}})$的。
带修改莫队需要注意的地方:每个询问要记录这个询问之前的最后一个修改是哪个,每个修改要记录修改之前的值以方便撤销。修改函数要写两个,一个是执行某个修改操作,一个是没有修改地从某个[l,r]走到[l',r']。
#include<cmath>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=;
char s[];
struct P{ int l,r,id,t; }a[N];
struct Q{ int x,y,lst; }b[N];
int x,y,n,m,A,B,sum,l,r,t,cnt[N],v[N],ans[N],lst[N],bel[N]; bool cmp(const P &x,const P &y){
if (bel[x.l]!=bel[y.l]) return bel[x.l]<bel[y.l];
if (bel[x.r]!=bel[y.r]) return bel[x.r]<bel[y.r];
return x.t<y.t;
} void mdf(int x,int y){
if (x>=l && x<=r){
cnt[v[x]]--; if (!cnt[v[x]]) sum--;
v[x]=y;
cnt[y]++; if (cnt[y]==) sum++;
}else v[x]=y;
} void upd(int x,int y){
int p=cnt[v[x]]; cnt[v[x]]+=y;
if (!p && cnt[v[x]]) sum++;
if (p && !cnt[v[x]]) sum--;
} void work(){
l=,r=,t=;
rep(i,,A){
while (t>a[i].t) mdf(b[t].x,b[t].lst),t--;
while (t<a[i].t) t++,mdf(b[t].x,b[t].y);
while (r<a[i].r) r++,upd(r,);
while (l>a[i].l) l--,upd(l,);
while (r>a[i].r) upd(r,-),r--;
while (l<a[i].l) upd(l,-),l++;
ans[a[i].id]=sum;
}
} int main(){
freopen("bzoj2120.in","r",stdin);
freopen("bzoj2120.out","w",stdout);
scanf("%d%d",&n,&m); int B=sqrt(n);
rep(i,,n) scanf("%d",&v[i]),lst[i]=v[i],bel[i]=(i-)/B+;
rep(i,,m){
scanf("%s%d%d",s,&x,&y);
if (s[]=='Q') a[++A]=(P){x,y,A,B}; else b[++B]=(Q){x,y,lst[x]},lst[x]=y;
}
sort(a+,a+A+,cmp); work();
rep(i,,A) printf("%d\n",ans[i]);
return ;
}
BZOJ2120数颜色(带修改莫队)的更多相关文章
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...
- BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]
BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...
- bzoj 2120 数颜色 带修改莫队
带修改莫队,每次查询前调整修改 #include<cstdio> #include<iostream> #include<cstring> #include< ...
- bzoj2120 数颜色——带修莫队
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 带修改的莫队: 用结构体存下修改和询问,排好序保证时间后就全局移动修改即可: 参考了T ...
- P1903 [国家集训队]数颜色 (带修改莫队)
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- BZOJ2120 数颜色 —— 待修改莫队
题目链接:https://vjudge.net/problem/HYSBZ-2120 2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: ...
- P1903 [国家集训队]数颜色 带修改莫队板子
大概就是要多加一维time 然后按照(l的块,r的块,time)为关键字排序 转移区间修改还是按照莫队的方式(每个修改要记修改前后的状态) 然后玄学dalao告诉窝块大小设为\(O(n^{\frac{ ...
- COGS.1901.[模板][国家集训队2011]数颜色(带修改莫队)
题目链接 COGS BZOJ2120 洛谷P1903 /* Add和Subd函数中的vis不能直接设为=1或=0 比如 l=1,r=0 -> l=3,r=5 时,[1,5]的vis标记全都是1 ...
- bzoj2120: 数颜色 带修莫队
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...
随机推荐
- css单行文本和多行文本溢出实现省略号显示
1.单行文本溢出 文本内容 <div class="singleLine"> HelloWorldHelloWorldHelloWorldHelloWorldHello ...
- 配置replica set的常见问题
总有人问起配置ReplicaSet不成功,总结了一下基本上的可能性就几种,检查步骤如下: 假设三台机器的IP分别是 A: 192.168.1.2 a.test.com B:192.168.1.3 b. ...
- 随机数生成 && 生成执行锁
生成随机数列: openssl rand -base64 uuidgen echo $RANDOM | md5sum echo $RANDOM | sha256sum 随机小写10个字母 随机数: [ ...
- SQLAlchemy-对象关系教程ORM-连接,子查询
对象关系教程ORM-连接 一:内连接 方法一: for u, a in session.query(User, Address).\ filter(User.id==Address.user_id). ...
- Nginx - upstream 模块及参数测试
目录 - 1. 前言- 2. 配置示例及指令说明 - 2.1 配置示例 - 2.2 指令 - 2.3 upstream相关变量- 3. 参数配置及测试 - 3.1 max_fa ...
- mac下---charles抓包https
网上找的很多安装包都有问题,终于找到个可用的! 下载地址: http://pan.baidu.com/s/1pLAONbX ———————————————————————————— 教程转载:htt ...
- java基础23 Math类和Random类
一.Math数学类 主要是提供很多数学的公式 1.1.Math类的常用方法 abs(int a):绝对值 ceil(double a):向上取整 floor(double a):向下取整 ...
- Python基础 - Ubuntu+Nginx+uwsgi+supervisor部署Flask应用
网上找了许多讲关于Flask应用部署的文章几乎都是一个helloworld的Demo,按照helloworld来部署都没问题,但实际项目部署时还是遇到了不少问题.在这里简单写下自己成功部署的过程,防止 ...
- MySQL 5.1完全卸载
第一步:控制面板里的增加删除程序内进行删除 第二步:删除MySQL文件夹下的my.ini文件,如果备份好,可以直接将文件夹全部删除 第三步:regedit进入注册表 HKEY_LOCAL_MACHIN ...
- php和mysql两种不同方式的分割字符串和类型转换
一.sql语句1.分割字符串方法:substring_index(字符串,'分隔符',正数从左数起几位/负数从右数起几位); 例如:subtring_index('aa_bb_cc_dd','_',1 ...