[Ynoi2019模拟赛]Yuno loves sqrt technology III
题目大意:
给你一个长为n的序列a,m次询问,每次查询一个区间的众数的出现次数,强制在线。
解题思路:
众所周知lxl是个毒瘤,Ynoi道道都是神仙题
首先得离散化。
分块后,预处理Fi,j表示第i∼j块的众数的出现次数。此处要用一个桶,空间复杂度O(n),时间复杂度O(n√n)。
用vector按顺序存每个数值所有元素的出现位置。
再记录每个元素在相应vector里的下标p。
以上空间复杂度都是O(n)的。
考虑询问,中间的直接使用预处理出的Fi,j的值即可。设当前的答案ans=Fi,j。
考虑边界的元素。
显然,由于边界的数最多2√n个,所以最多使得答案增加2√n。
我们只需要检查这些边角的元素,每次判断这些数的出现次数能否达到ans+1。
对于左边的边角元素x,我们在相应的vector里找到下标为px+ans的元素yy,若y⩽ry⩽r,则说明该数值在范围内有至少ans+1ans+1个数,暴力++ans即可。
对于右边的边角元素x,我们在相应的vector里找到下标为px−ans的元素yy,若y⩾ly⩾l,则说明该数值在范围内有至少ans+1ans+1个数,暴力++ans即可。
每次询问对O(√n)个元素检查,++ans的次数为O(√n)次。所以查询的时间复杂度为O(m√n)。
总时间复杂度O((n+m)√n),空间复杂度O(n),lxl说达到了下界。
C++ Code:
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
#define siz 708
#define N 500001
class istream{
char buf[],*s;
public:
inline istream(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif
fread(s=buf,,,stdin);
fclose(stdin);
}
inline istream&operator>>(int&rhs){
int f=rhs=;
for(;!isdigit(*s);++s)f=*s=='-';
for(;isdigit(*s);)
rhs=(rhs<<)+(rhs<<)+(*s++^'');
if(f)rhs=-rhs;
return*this;
}
}cin;
class ostream{
char buf[],*s;
public:
inline ostream(){s=buf;}
inline ostream&operator<<(int rhs){
if(rhs<)*s++='-',rhs=-rhs;
if(rhs==){
*s++='';
return*this;
}
static int w;
for(w=;w<=rhs;w*=);
for(w/=;w;w/=)*s++=(rhs/w)^'',rhs%=w;
return*this;
}
inline ostream&operator<<(const char&rhs){*s++=rhs;return*this;}
inline~ostream(){
fwrite(buf,,s-buf,stdout);
}
}cout;
int n,m,L[],R[],bel[N],blocks,mx[][],ans,tot[N],wz[N],a[N];
void init(){
blocks=(n-)/siz+;
for(int i=;i<=blocks;++i)L[i]=R[i-]+,R[i]=i*siz;
R[blocks]=n;
for(int i=;i<=blocks;++i){
memset(tot,,sizeof tot);
for(int j=L[i];j<=R[i];++j)bel[j]=i;
for(int j=i;j<=blocks;++j){
int&F=mx[i][j];
F=mx[i][j-];
for(int k=L[j];k<=R[j];++k)
F=std::max(F,++tot[a[k]]);
}
}
}
std::vector<int>ls,v[N];
int main(){
ls.push_back(-);
cin>>n>>m;
for(int i=;i<=n;ls.push_back(a[i++]))cin>>a[i];
std::sort(ls.begin(),ls.end());
ls.erase(std::unique(ls.begin(),ls.end()),ls.end());
for(int i=;i<=n;++i)v[a[i]=std::lower_bound(ls.begin(),ls.end(),a[i])-ls.begin()].push_back(i),wz[i]=v[a[i]].size()-;
init();
memset(tot,,sizeof tot);
while(m--){
int l,r;cin>>l>>r;
l^=ans,r^=ans;
ans=;
if(bel[l]==bel[r]){
for(int i=l;i<=r;++i)ans=std::max(ans,++tot[a[i]]);
for(int i=l;i<=r;++i)tot[a[i]]=;
}else{
ans=mx[bel[l]+][bel[r]-];
for(int i=l;i<=R[bel[l]];++i){
int it=wz[i];
while(it+ans<v[a[i]].size()&&v[a[i]][it+ans]<=r)++ans;
}
for(int i=L[bel[r]];i<=r;++i){
int it=wz[i];
while(it-ans>=&&v[a[i]][it-ans]>=l)++ans;
}
}
cout<<ans<<'\n';
}
return ;
}
[Ynoi2019模拟赛]Yuno loves sqrt technology III的更多相关文章
- [Luogu5048] [Ynoi2019模拟赛]Yuno loves sqrt technology III[分块]
题意 长为 \(n\) 的序列,询问区间众数,强制在线. \(n\leq 5\times 10^5\). 分析 考虑分块,暴力统计出整块到整块之间的众数次数. 然后答案还可能出现在两边的两个独立的块中 ...
- [luogu5048] [Ynoi2019模拟赛] Yuno loves sqrt technology III
题目链接 洛谷. Solution 思路同[BZOJ2724] [Violet 6]蒲公英,只不过由于lxl过于毒瘤,我们有一些更巧妙的操作. 首先还是预处理\(f[l][r]\)表示\(l\sim ...
- [洛谷P5048][Ynoi2019模拟赛]Yuno loves sqrt technology III
题目大意:有$n(n\leqslant5\times10^5)$个数,$m(m\leqslant5\times10^5)$个询问,每个询问问区间$[l,r]$中众数的出现次数 题解:分块,设块大小为$ ...
- 洛谷P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III(分块)
传送门 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 用蒲公英那个分块的方法做结果两天没卡过去→_→ 首先我们分块,预处理块与块之间的答案,然后每次询问的时候拆成整块和两边剩下的元素 整块的答案很简 ...
- Luogu P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III 分块
这才是真正的$N\sqrt{N}$吧$qwq$ 记录每个数$vl$出现的位置$s[vl]$,和每个数$a[i]=vl$是第几个$vl$,记为$P[i]$,然后预处理出块$[i,j]$区间的答案$f[i ...
- P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]
为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...
- 洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)
题面传送门 qwq 感觉跟很多年前做过的一道题思路差不多罢,结果我竟然没想起那道题?!!所以说我 wtcl/wq 首先将 \(a_i\) 离散化. 如果允许离线那显然一遍莫队就能解决,复杂度 \(n\ ...
- [Ynoi2019模拟赛]Yuno loves sqrt technology II(二次离线莫队)
二次离线莫队. 终于懂了 \(lxl\) 大爷发明的二次离线莫队,\(\%\%\%lxl\) 二次离线莫队,顾名思义就是将莫队离线两次.那怎么离线两次呢? 每当我们将 \([l,r]\) 移动右端点到 ...
- [Ynoi2019模拟赛]Yuno loves sqrt technology II
题目大意: 给定一个长为\(n\)的序列,\(m\)次询问,每次查询一个区间的逆序对数. 32MB. 解题思路: 出题人题解 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 二次离线莫队. 对于每个区 ...
随机推荐
- 常用命令和sql
常用命令: mvn idea:idea //生成.ipr项目文件 mvn clean install -Dmaven.test.skip=true mvn install:install-file - ...
- left join on 后and 和 where 的区别
SELECT * FROM student a LEFT JOIN sc b ON a.Sid = b.Sid AND a.Sname="赵雷" 结果:(left join 左连接 ...
- DataGridView中的DataGridViewComboBoxColumn 让其值改变联动
在工作中自己也遇到过这类问题, 最近也有很多人问我这个问题, 就此机会写出来记录一下. 首先,顾名思义,值改变事件我们会想到 dataGridView1_CellValueChanged 这个事件,想 ...
- Thread 详解
转自:http://www.mamicode.com/info-detail-517008.html 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 ...
- Ubuntu16.04安装MongoDB的Ruby驱动
背景: 1. ruby的安装方式:sudo apt-get install ruby 2. mongod服务已开启 3. ruby版本:2.3, gem已安装 安装驱动的步骤: 1. gem inst ...
- Jsoup获取全国地区数据(省市县镇村)
最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的.各种度娘,各种谷歌,都没找到一个完整的数据.最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到 ...
- 2018-2019-2 学号20175223 实验二《Java面向对象程序设计》实验报告
目录 北京电子科技学院(BESTI)实验报告 实验名称:实验二 面向对象程序设计 实验内容.步骤与体会: 一.实验二 面向对象程序设计-1 二.实验二 面向对象程序设计-2 三.实验二 面向对象程序设 ...
- 北大poj- 1034
The dog task Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3272 Accepted: 1313 Sp ...
- java中对类中成员的排序
要求:编写一个程序.程序中定义一个类circle,其中有数据成员radius:创建一个有5个circle型元素的数组,其radius值分别为2.10.8.4.121.调用Arrays.sort()给这 ...
- 2018-计算机系机试(第二批)-B-二进制输出
B. 二进制输出 单点时限: 1.0 sec 内存限制: 256 MB 输入一个十进制表示的非负整数,输出其 8 位二进制表示. 例如:输入 10 ,输出 00001010. 输入格式 一行一个非负整 ...