当前位置: 首页 > news >正文

回滚莫队模版

回滚莫队模版

题意

给定数列,查询 \(l\)\(r\) 的众数。

思路

如果考虑暴力,我们需要一遍遍的遍历数列的数,然后求众数,但是这样效率太低了。

思考怎么优化,首先想到的线段树,但很容易发现这个众数一点都不好维护,想要全部记录,发现查找和合并的时间复杂度似乎都是 \(O(n)\) 并不好用。

容易发现这个是离线查询,可以用莫队求解,但是它不能做到删除(会退)的操作,也就是说,我们不能像莫队模版一样作奇偶优化,和左边界随便走。

所以我们参照莫队的思路,对同一块内线段的右端点来扩展右边界,而对于随机移动的左端点,我们每次移动左端点的时候,都记录一下这个起点的信息,每次做完再会退回来。至于哪里作为起点,由于一个块内所有左端点都小于这个块的右端点所以选择这个块的右端点作为起点。

code

#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn = 3e5+10;
constexpr int maxm = 700;
constexpr int mod = 10007;
constexpr int INF = 0x3f3f3f3f3f3f3f3f;
void read(int &);int n,n_n;
int idx[maxn];// i对应的块的id
int wi[maxn]; // 离散化的值
int tmp[maxn];// 用到再说,用法。。是个tmp
int ww[maxn]; // 原值
int cnt[maxn];// 离散化的值的计数typedef struct node
{int l,r,id;bool operator<(const node &t) const{return idx[l]==idx[t.l] ? r<t.r : idx[l]<idx[t.l];// 一块内按右端点排,不然按块排}
}node;node qwq[maxn];// 询问
int ans[maxn];// 答案void bf(int id) // 暴力处理小的查询
{int macnt=0;int maid=0;// 使用0而不是INF, 不然会reint top=0;// tmp临时存放修改的cntfor(int i=qwq[id].l; i<=qwq[id].r; ++i){if(!cnt[wi[i]]){tmp[++top]=wi[i];// wa过,这里要存i离散化后的值}++cnt[wi[i]];if(cnt[wi[i]]>macnt){macnt=cnt[wi[i]];maid=i;}else if(cnt[wi[i]]==macnt && ww[i]<ww[maid])// 如果由有更小的数字{maid=i;}}ans[qwq[id].id]=ww[maid];// 存入答案,注意传进来id是块的idfor(int i=1;i<=top;++i){cnt[tmp[i]]=0;}
}signed main()
{#ifndef ONLINE_JUDGEfreopen("cjdl.in","r",stdin);freopen("cjdl.out","w",stdout);#endif // ONLINE_JUDGEread(n);n_n=sqrt(n);for(int i=1;i<=n;++i){read(wi[i]);idx[i]=(i-1)/n_n+1;tmp[i]=wi[i];// 暂时存值,用于离散化ww[i]=wi[i];}sort(tmp+1,tmp+1+n);int id_w=unique(tmp+1,tmp+1+n)-tmp-1;for(int i=1;i<=n;++i){read(qwq[i].l);read(qwq[i].r);qwq[i].id=i;wi[i]=lower_bound(tmp+1,tmp+1+id_w,wi[i])-tmp;}sort(qwq+1,qwq+1+n);int now=1;// 存储处理到了哪个块for(int i=1;i<=n_n+10;++i){int L=(i-1)*n_n+1;int R=i*n_n;if(L>n){break;}int r=R, l=R+1;// 初始设为空,先++再计算int maid = 0;// 下标int macnt=0;for(;now<=n && qwq[now].l<=R;++now){if(qwq[now].r<R)// 在一个快内暴力作{bf(now);continue;}while(r<qwq[now].r)// 扩展右边界,注意不要吧x和r混起来{++r;int x=wi[r];++cnt[x];if(cnt[x]>macnt){macnt=cnt[x];maid=r;}else if(cnt[x]==macnt && ww[r]<ww[maid]){maid=r;}}int old_id=maid;int old_cnt=macnt;while(l>qwq[now].l)// 扩展右边界{--l;int x=wi[l];++cnt[x];if(cnt[x]>macnt){macnt=cnt[x];maid=l;}else if(cnt[x]==macnt && ww[l]<ww[maid]){maid=l;}}ans[qwq[now].id]=ww[maid];while(l<=R)// 回滚{--cnt[wi[l++]];}macnt=old_cnt;// 恢复l 在R+1的情况maid=old_id;}memset(cnt,0,sizeof cnt);// 清空}for(int i=1;i<=n;++i){printf("%lld\n",ans[i]);}return 0;
}void read(int &x)
{x=0;int f=1;signed c=getchar();while(!isdigit(c)){if(c=='-'){f=-1;}c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x*=f;
}
http://www.jsqmd.com/news/47701/

相关文章:

  • 2025年拉袋离心机订制厂家权威推荐榜单:碟式离心机/卧螺离心机/活塞推料离心机源头厂家精选
  • Linux中: 通过编译安装的方式升级 OpenSSH 服务
  • 纵观当代现状,70年代出生的人,可能别具一格
  • #题解#洛谷 P4375 Out of Sorts G #离散化#
  • hbase上如何导入python包
  • 轻薄手机推荐:不止于轻,2025 旗舰体验榜 - 详解
  • Git为什么要有submodule呢?
  • 征程 6E/M 计算平台部署指南
  • 2025年重庆废气收集处理机构权威推荐榜单:废气处理/废气治理/废气处理设备源头机构精选
  • 详细介绍:第三章 FreeRTOS 任务相关 API 函数
  • 数据库的安全与保护(下) - 实践
  • 2025年口碑好的江苏婚纱照/婚前影像/小众婚纱照/园林婚纱照/光影婚纱照/外景婚纱照/秀禾婚纱照/中式婚纱照/结婚照品牌推荐:弥素摄影领跑
  • 2025年江苏婚纱照/婚前影像/小众婚纱照/园林婚纱照/光影婚纱照/外景婚纱照/秀禾婚纱照/中式婚纱照/结婚照品牌口碑推荐榜:弥素摄影领跑行业
  • 打印机字体漏洞分析:CVE-2024-12649技术深度解析
  • 2025年11月22日
  • 2025年德商数控母线加工机实力厂家权威推荐榜单:德商母线加工机/德商铜排加工机/德商母排加工机源头厂家精选
  • 【Java后端进行ai coding实践系列】如何使用ai coding达成计划任务增删改查
  • 2025-11-21 hetao1733837的刷题记录
  • 2025 最新腻子粉厂家推荐!环保与性能双优腻子粉品牌排行榜,涵盖母婴级 / 工程级产品权威测评儿童级健康腻子粉/工程腻子粉/工程腻子粉施工/建筑腻子粉公司推荐
  • java freemarker(ftl)模板填充导出PDF,支持中文乱码
  • 2025年广东洁净度检测公司权威推荐榜单:广东医院(诊所)洁净环境检测/广东空气净化器检测平台/广东新风机检测服务机构精选
  • C# Avalonia 18- ControlTemplates - FlipPanelTest
  • 2025 最新仿石漆厂家权威推荐榜:真石漆 / 绿色环保仿石漆优质品牌精选仿石漆/真石漆/绿色真石漆/有资质的仿石漆公司推荐
  • 2025年纱线烘干机制造厂权威推荐榜单:气流烘干机/筒子烘干机/快速烘干机源头制造厂精选
  • CTF逆向Re:零基础系统性入门教程-5-动态调试
  • CF1817B Fish Graph
  • CF1630C Paint the Middle
  • CF1707B Difference Array
  • P3113 [USACO14DEC] Marathon G
  • 封装map和set(红黑树作为底层结构如何完成map和set插入遍历)