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 ...
随机推荐
- C# Json字符串反序列化
using DevComponents.DotNetBar; using MyControl; using Newtonsoft.Json; using System; using System.Co ...
- 关于UDP数据报引发“异步错误”的疑问
在UNP卷一第三版的第8章8.9小节中说到:如果udp服务器没有启动,udp客户端在使用sendto发送一行文本后,将会等待一个永远也不会出现的应答从而阻塞在recvfrom调用上. 由于服务器段不存 ...
- translate 与 相对、绝对定位
垂直水平居中是日常前端开发当中一个常见的需求,在支持 CSS3 属性的现代浏览器当中,有一个利用 CSS3 属性的垂直水平居中方法: position absolute; :; :; :transla ...
- vue中使用cookie记住用户上次选择(本次例子中为下拉框)
最近工作中碰到一个需求,添加一条数据时,自动记住上次选择的下拉框的数据,刚开始觉得没思路,后来请教了项目组长,组长直接一句,这不很简单吧,直接用cookie,我:....... 好吧,都王的差不多了, ...
- 如何基于Spring Boot搭建一个完整的项目
前言 使用Spring Boot做后台项目开发也快半年了,由于之前有过基于Spring开发的项目经验,相比之下觉得Spring Boot就是天堂,开箱即用来形容是绝不为过的.在没有接触Spring B ...
- linux强制踢掉登录用户【转】
[root@Wang ~]# w :: up :, users, load average: 0.71, 0.58, 0.57 USER TTY FROM LOGIN@ IDLE JCPU PCPU ...
- 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)
Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...
- python基础-类的继承
继承:承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”.“父类. 继承的过程,就是从一般到特殊的过程.要实现继承,可以通过“继承”(Inheritance)和“组合”(Compositio ...
- 再谈OPENCV(转)
转自:http://blog.csdn.net/carson2005/article/details/6979806 尽管之前写过一篇关于OpenCV的介绍(http://blog.csdn.net/ ...
- 洛谷P1186玛丽卡
传送门啦 先跑一遍最短路,将最短路的路径记录下来,然后枚举每一条最短路的边,将其断掉,记录此时的1-n的时间,取其中最大的一个时间即为所求. (通过 $ cut[][] $ 和 $ f[] $ 进行操 ...