[ Luogu 3709 ] 大爷的字符串题
\(\\\)
Description
原题题面太过混乱出题人语文凉凉
给出一个长为 \(n\) 的数列 \(A\) ,多次询问:
对于一个区间 \([L_i,R_i]\),把区间内的所有数最少划分成多少个数集,使得每一个集合内没有相同元素。
- \(A_i\le 10^9,n,m\le 2\times 10^5\)
\(\\\)
Solution
题目的模型很容易转化成区间众数问题。
莫队求解区间众数。
首先数据范围是假的,离散化之后就开的下桶了。
对于区间扩张,肯定是加一下桶,然后跟当前答案取 \(max\) 。
问题在于区间缩小时,删除一个数怎么搞。
\(\\\)
开始有一个 too simple 想法,是用堆去维护当前答案区间内所有数出现个数,然后懒惰删除法,每次更新时判断一下堆顶是否正确。
想一想是对的,但是 \(O(N\sqrt NlogN)\) 的复杂度对于 \(2\times 10^5\) 很吃力。
\(\\\)
一个机智的做法。
设 \(cnt[i]\) 表示 \(bkt[x]=i\) 的个数,也就是当前区间里出现次数为 \(i\) 的数的个数。
空间没有问题,因为最多出现数列长度的次数。
这样一来修改就容易了很多,减的时候只需要判断一下,当前数对应的 \(cnt\) 是否 \(>1\) 即可。
注意加减是对 \(cnt\) 和 \(bkt\) 的同时更新。
\(\\\)
Code
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200000
#define R register
#define gc getchar
using namespace std;
inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}
int n,m,ans,bl[N],cnt[N],bkt[N],s[N],tmp[N];
struct Q{int l,r,ans,id;}q[N];
inline bool cmp1(Q x,Q y){
return bl[x.l]==bl[y.l]?x.r<y.r:bl[x.l]<bl[y.l];
}
inline bool cmp2(Q x,Q y){return x.id<y.id;}
inline void add(int p){
--cnt[bkt[s[p]]];
++cnt[++bkt[s[p]]];
ans=max(ans,bkt[s[p]]);
}
inline void del(int p){
--cnt[bkt[s[p]]];
if(ans==bkt[s[p]]&&!cnt[bkt[s[p]]]) --ans;
++cnt[--bkt[s[p]]];
}
int main(){
n=rd(); m=rd();
int t=sqrt(n),tot=0;
for(R int i=1,cntt=1;i<=n;++i){
tmp[i]=s[i]=rd();
if(i%t==0) ++cntt;
bl[i]=cntt;
}
sort(tmp+1,tmp+1+n);
for(R int i=1;i<=n;++i){
tmp[++tot]=tmp[i];
while(tmp[i+1]==tmp[i]&&i<=n) ++i;
}
for(R int i=1;i<=n;++i) s[i]=lower_bound(tmp+1,tmp+1+tot,s[i])-tmp;
for(R int i=1;i<=m;++i){
q[i].l=rd(); q[i].r=rd(); q[i].id=i;
}
sort(q+1,q+1+m,cmp1);
bkt[s[1]]=cnt[1]=ans=1;
int nowl=1,nowr=1;
for(R int i=1;i<=m;++i){
while(nowl<q[i].l){del(nowl);++nowl;}
while(nowl>q[i].l){--nowl;add(nowl);}
while(nowr>q[i].r){del(nowr);--nowr;}
while(nowr<q[i].r){++nowr;add(nowr);}
q[i].ans=ans;
}
sort(q+1,q+1+m,cmp2);
for(R int i=1;i<=m;++i) printf("%d\n",-q[i].ans);
return 0;
}
[ Luogu 3709 ] 大爷的字符串题的更多相关文章
- luogu 3709 大爷的字符串题 构造 莫队 区间众数
题目链接 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区间中随机拿出一个字符\(x\),然后把\(x\)从这个区间中删除,你要维护一个集合S 如果\(S\)为空,你\(r ...
- luogu P3709 大爷的字符串题
二次联通门 : luogu P3709 大爷的字符串题 /* luogu P3709 大爷的字符串题 莫队 看了半天题目 + 题解 才弄懂了要求什么... 维护两个数组 一个记录数字i出现了几次 一个 ...
- 【luogu P3709 大爷的字符串题】 题解
题目链接:https://www.luogu.org/problemnew/show/P3709 离散化+区间众数..? #include <iostream> #include < ...
- P3709 大爷的字符串题 (莫队)
题目 P3709 大爷的字符串题 题意:求\([l,r]\)中众数的个数. 解析 维护两个数组: \(cnt[x]\),数\(x\)出现的次数. \(sum[x]\),出现次数为\(x\)的数的个数. ...
- AC日记——大爷的字符串题 洛谷 P3709
大爷的字符串题 思路: 莫队,需开O2,不开50: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20000 ...
- P3709 大爷的字符串题(莫队+结论)
题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...
- 洛谷 P3709 大爷的字符串题
https://www.luogu.org/problem/show?pid=3709 题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个 ...
- 洛谷P3709 大爷的字符串题(莫队)
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...
- P3709 大爷的字符串题(50分)
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...
随机推荐
- Android 源码架构
我们都知道Android系统是一个开源工程,在网上可以下载到源代码. 一般在网上搜索一下,就会找到各种下载源代码的方法,比如使用Git和Repo,android源代码下载的网址是http://andr ...
- docker pure-ftp 搭建ftp服务器
参考:https://hub.docker.com/r/stilliard/pure-ftpd/ docker-compose.yml: ftp: image: stilliard/pure-ftpd ...
- POJ1077 Eight —— 反向BFS
主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:以数组充当队列,利用结构体中的pre追溯上一个状态在数组(队列)中的下标: #incl ...
- Silverlight实用窍门系列:1.Silverlight读取外部XML加载配置---(使用WebClient读取XAP包同目录下的XML文件))【附带实例源码】
使用WebClient读取XAP包同目录下的XML文件 我们想要读取XAP包下面的XML文件,需要将此XML文件放在加载XAP包的网页的目录中去,然后使用URI方式读取此URL方式下的XML文件. 首 ...
- 使用gcc找出头文件的路径
参考 http://stackoverflow.com/questions/13079650/how-can-i-find-the-header-files-of-the-c-programming- ...
- codeforces 696A A. Lorenzo Von Matterhorn(水题)
题目链接: A. Lorenzo Von Matterhorn time limit per test 1 second memory limit per test 256 megabytes inp ...
- POJ3020 二分图匹配——最小路径覆盖
Description The Global Aerial Research Centre has been allotted the task of building the fifth gener ...
- CCRect 构造函数的几个参数解释
转自: http://blog.163.com/hzklclick_wy/blog/static/21550517520137139511839/ void CCRect::setRect(f ...
- IOS:程序的退出、App间的跳转
今天在做一个音乐播放器的项目,发现这个点击退出程序的功能不能实现终于找到了一些有用的资料,就去网上看了半天资料,下面是退出程序的代码: 在动画里面可以自己添加一些,动画,达到相应的效果. AppDel ...
- View Programming Guide for iOS ---- iOS 视图编程指南(三)---Windows
Windows Every iOS application needs at least one window—an instance of the UIWindow class—and some m ...