洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)
qwq 感觉跟很多年前做过的一道题思路差不多罢,结果我竟然没想起那道题?!!所以说我 wtcl/wq
首先将 \(a_i\) 离散化。
如果允许离线那显然一遍莫队就能解决,复杂度 \(n\sqrt{n}\)。
那如果强制在线怎么办呢?
既然离线都只能做到 \(n\sqrt{n}\),那在线肯定至少 \(n\sqrt{n}\) 咯
考虑将原序列分块,我们预处理处 \(mx_{i,j}\) 表示第 \(i\) 块开头到第 \(j\) 块结尾的区间中出现次数最多的值的出现次数。这个显然可以 \(n\sqrt{n}\) 求出,具体来说枚举开头的块 \(i\) 并实时维护一个桶 \(cnt_i\),然后一遍向后扫描一遍更新答案即可。
接下来考虑怎样求出答案:
- 如果 \(l,r\) 在同一块中那直接暴力统计答案即可,复杂度 \(\sqrt{n}\)。
- 如果 \(l,r\) 不在同一块中,我们掏出求得的 \(mx\) 数组,先令 \(ans=mx_{bel_l+1,bel_r-1}\),也就是 \([l,r]\) 中间整块的答案。然后考虑边角元素对答案的影响。我们对每个值 \(v\) 开一个
std::vector<int>\(pos\) 维护其出现的位置,记 \(p_i\) 为 \(i\) 在 \(pos_{a_i}\) 中的位置。对于左边的边角元素 \(i\in[l,R[bel[r]]]\),如果 \(i\) 能使答案变得更优,那么 \(a_i\) 在 \([l,r]\) 中出现的次数应当大于 \(ans\),换句话说,\(pos[a[i]][p[i]+ans]\leq r\),那我们可以暴力往右移,每次答案加一,直到 \(pos[a[i]][p[i]+ans]>r\)。对于右边的边角元素也同理,不难发现边角元素最多 \(2\sqrt{n}\) 个,故 \(ans\) 最多自增 \(2\sqrt{n}\) 次,故查询复杂度 \(\sqrt{n}\)。
总复杂度 \(n\sqrt{n}\),只要常数稍微小一点即可通过本题时限。
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=5e5;
const int MAX_BLK=710;
int n,qu,a[MAXN+5],key[MAXN+5],uni[MAXN+5],num;
int blk,blk_cnt,L[MAX_BLK+5],R[MAX_BLK+5],bel[MAXN+5];
int mx[MAX_BLK+5][MAX_BLK+5],cnt[MAXN+5];
vector<int> pos[MAXN+5];int p[MAXN+5];
int main(){
scanf("%d%d",&n,&qu);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),key[i]=a[i];
sort(key+1,key+n+1);key[0]=-1;
for(int i=1;i<=n;i++) if(key[i]!=key[i-1]) uni[++num]=key[i];
for(int i=1;i<=n;i++) a[i]=lower_bound(uni+1,uni+num+1,a[i])-uni;
blk=(int)pow(n,0.5);blk_cnt=(n-1)/blk+1;
for(int i=1;i<=blk_cnt;i++){
L[i]=(i-1)*blk+1;R[i]=min(i*blk,n);
for(int j=L[i];j<=R[i];j++) bel[j]=i;
}
for(int i=1;i<=blk_cnt;i++){
memset(cnt,0,sizeof(cnt));int ret=0;
for(int j=i;j<=blk_cnt;j++){
for(int k=L[j];k<=R[j];k++){
cnt[a[k]]++;chkmax(ret,cnt[a[k]]);
} mx[i][j]=ret;
}
}
for(int i=1;i<=n;i++) pos[a[i]].pb(i),p[i]=pos[a[i]].size()-1;
int ans=0;memset(cnt,0,sizeof(cnt));
while(qu--){
int l,r;scanf("%d%d",&l,&r);l^=ans;r^=ans;ans=0;
if(bel[l]==bel[r]){
for(int i=l;i<=r;i++) cnt[a[i]]++;
for(int i=l;i<=r;i++) chkmax(ans,cnt[a[i]]);
for(int i=l;i<=r;i++) cnt[a[i]]--;
printf("%d\n",ans);
} else {
ans=mx[bel[l]+1][bel[r]-1];
for(int i=l;i<=R[bel[l]];i++){
int cur=p[i];
while(cur+ans<pos[a[i]].size()&&pos[a[i]][cur+ans]<=r)
++ans;
}
for(int i=L[bel[r]];i<=r;i++){
int cur=p[i];
while(cur-ans>=0&&pos[a[i]][cur-ans]>=l)
++ans;
}
printf("%d\n",ans);
}
}
return 0;
}
/*
10 1
1 2 3 3 2 3 3 1 1 2
4 10
*/
洛谷 P5048 - [Ynoi2019 模拟赛] Yuno loves sqrt technology III(分块)的更多相关文章
- [洛谷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 ...
- 洛谷 P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I(分块+卡常)
洛谷题面传送门 zszz,lxl 出的 DS 都是卡常题( 首先由于此题强制在线,因此考虑分块,我们那么待查询区间 \([l,r]\) 可以很自然地被分为三个部分: 左散块 中间的整块 右散块 那么这 ...
- P5048 [[Ynoi2019模拟赛]Yuno loves sqrt technology III]
为什么我感觉这题难度虚高啊-- 区间众数的出现次数- 计算器算一下 \(\sqrt 500000 = 708\) 然后我们发现这题的突破口? 考虑分块出来[L,R]块的众数出现个数 用 \(\text ...
- [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 ...
- [Ynoi2019模拟赛]Yuno loves sqrt technology III
题目大意: 给你一个长为n的序列a,m次询问,每次查询一个区间的众数的出现次数,强制在线. 解题思路: 出题人题解 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 首先得离散化. 分块后,预处理Fi, ...
- [Ynoi2019模拟赛]Yuno loves sqrt technology I
题目描述 给你一个长为n的排列,m次询问,每次查询一个区间的逆序对数,强制在线. 题解 MD不卡了..TMD一点都卡不动. 强制在线的话也没啥好一点的方法,只能分块预处理了. 对于每个块,我们设lef ...
随机推荐
- oo第二次博客-三次电梯调度的总结与反思
本单元从电梯调度相关问题层层深入,带领我们学习并运用了了多线程相关的知识. 三次电梯调度依次为单电梯单容量.单电梯可携带.多电梯可携带. 一.我的设计 在第一次作业中,使用了最简单的FIFO调度方法. ...
- InitSpatialMetaData()速度慢的问题
解决方法:with sqlite3.connect(dbfile) as con: con.enable_load_extension(True) con.execute("SELECT l ...
- 实验5:开源控制器实践——POX
一.实验目的 1.能够理解 POX 控制器的工作原理: 2.通过验证POX的forwarding.hub和forwarding.l2_learning模块,初步掌握POX控制器的使用方法: 3.能够运 ...
- Luogu P4390 [BOI2007]Mokia 摩基亚 | CDQ分治
题目链接 $CDQ$分治. 考虑此时在区间$[l,r]$中,要计算$[l,mid]$中的操作对$[mid+1,r]$中的询问的影响. 计算时,排序加上树状数组即可. 然后再递归处理$[l,mid]$和 ...
- Linux oracle 导入sql文件
1.@sql文件的路径 SQL>@/data/xx.sql; 2.导入完毕 commit;
- 几十行js实现很炫的canvas交互特效
几十行js实现很炫的canvas交互特效 废话不多说,先上效果图! 本篇文章的示例代码都是抄的一个叫Franks的老外在yutube上的一个教学视频,他还出了很多关于canvas的视频,十分值得学习, ...
- 线程创建,属性设置与获得,等待线程结束,线程中fork,以及执行exec()
这篇博客的形式我想以分析代码不同情况为主: 点击(此处)折叠或打开 #include<stdio.h> #include<pthread.h> #include<time ...
- Javafx-【直方图】文本频次统计工具 中文/英文单词统计
上周倒腾了下 javafx,本来是做平时成绩系统.跟老师提了一下 javafx,他突然兴起,发了个统计中文和英文单词并以直方图显示的实验......只给两三天的期限,笑着说考验我们的潜力SOS,于是带 ...
- 常用的 21 条 Linux 命令,生产力必备
一.文件和目录 1. cd命令 (它用于切换当前目录,它的参数是要切换到的目录的路径,可以是绝对路径,也可以是相对路径) cd /home 进入 '/ home' 目录 cd .. 返回上一级目录 c ...
- [linux]centos7.4上安装MySQL-8.0.11【完美安装】
版本声明 centos7.4 MySQL-8.0.11 1.我用的阿里云的虚拟主机,刚从windows换到linux,需要装下常用工具 #安装下sz rz常用到上传下载的命令 yum install ...