[bzoj3489] A simple rmq problem 解题报告

2024-03-10 19:18

本文主要是介绍[bzoj3489] A simple rmq problem 解题报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说几种比较傻逼的做法:
考虑一个点i,设它前面第一个和它相等的点的位置是 lasti (若没有就是0),设它后面第一个和它相等的点的位置是 nexti (如果没有就是n+1),则它会产生贡献的区间[l,r]要求 lasti+1li,irnexti1 。所以如果把询问的区间看作平面上的点,这就相当于是对一个矩形产生贡献,考虑到这题要求离线,所以我们就可以用二维可持久化线段树来搞。。
就这样跑了17s。。

我们反过来考虑,考虑一次询问对点的要求,是 i[l,r],lasti[1,l),nexti(i,n] ,所以我们可以就可以用三维k-d树搞出这个东西来。注意到 lasti nexti 都是一个类似前缀和的东西,所以我们前缀和一维,用二维可持久化k-d树。
就这样跑了10s。。

代码(可持久化k-d树):

#include<cstdio>
#include<iostream>
using namespace std;
#include<algorithm>
#include<cstring>
#include<cmath>
const int N=1e5+5,M=2e5+5;
int a[N];
int pos[N];void in(int &x){char c=getchar();while(c<'0'||c>'9')c=getchar();for(x=0;c>='0'&&c<='9';c=getchar())x=x*10+(c^'0');
}const int Log=18;
struct KS{int ls,rs;int lx,rx,ly,ry;int max;
}kdt[N*(Log+2)];
int root[N];
int ktot=1;
struct PS{int x,y;
}point[N];
bool cmpx(const PS & a,const PS & b){return a.x<b.x;
}
bool cmpy(const PS & a,const PS & b){return a.y<b.y;
}
bool inrange(int lx,int rx,int ly,int ry,int Lx,int Rx,int Ly,int Ry){return Lx<=lx&&rx<=Rx&&Ly<=ly&&ry<=Ry;
}
void out(int node){printf("%d{[%d,%d]-[%d,%d] max=%d}\n",node,kdt[node].lx,kdt[node].rx,kdt[node].ly,kdt[node].ry,kdt[node].max);
}
void build(int &node,int pl,int pr,bool depth){node=ktot++;kdt[node].lx=kdt[node].rx=point[pl].x;kdt[node].ly=kdt[node].ry=point[pl].y;for(int i=pl+1;i<=pr;++i){kdt[node].lx=min(kdt[node].lx,point[i].x);kdt[node].rx=max(kdt[node].rx,point[i].x);kdt[node].ly=min(kdt[node].ly,point[i].y);kdt[node].ry=max(kdt[node].ry,point[i].y);}//printf("[%d,%d]=",pl,pr);//out(node);if(pl!=pr){int pm=pl+pr>>1;if(depth)nth_element(point+pl,point+pm,point+pr+1,cmpx);else nth_element(point+pl,point+pm,point+pr+1,cmpy);//for(int i=pl;i<=pr;++i)printf("(%d,%d) ",point[i].x,point[i].y);//puts("");build(kdt[node].ls,pl,pm,depth^1);build(kdt[node].rs,pm+1,pr,depth^1);}
}
void add(int &node,int pl,int pr,int x,int A){//printf("Add (%d) at ",A);kdt[ktot]=kdt[node];//out(node);node=ktot++;kdt[node].max=max(kdt[node].max,A);//out(node);if(pl!=pr){//out(kdt[node].ls),out(kdt[node].rs);if(x<=pl+pr>>1)add(kdt[node].ls,pl,pl+pr>>1,x,A);else add(kdt[node].rs,(pl+pr>>1)+1,pr,x,A);}
}
int lastans;
void query(int node,int Lx,int Rx,int Ly,int Ry){if(kdt[node].rx<Lx||kdt[node].lx>Rx||kdt[node].ly>Ry||kdt[node].ry<Ly)return;if(inrange(kdt[node].lx,kdt[node].rx,kdt[node].ly,kdt[node].ry,Lx,Rx,Ly,Ry)){//printf("Get:");//out(node);lastans=max(lastans,kdt[node].max);}if(kdt[node].max<=lastans)return;query(kdt[node].ls,Lx,Rx,Ly,Ry),query(kdt[node].rs,Lx,Rx,Ly,Ry);
}struct PointS{int last,i,next;bool operator < (const PointS & o)const{return last<o.last;}
}pnt[N];
int main(){freopen("bzoj_3489.in","r",stdin);int n,m;in(n),in(m);for(int i=1;i<=n;++i)in(a[i]);for(int i=1;i<=n;++i){pnt[i].last=pos[a[i]]+1;pos[a[i]]=i;}for(int i=n;i;--i)pos[a[i]]=n+1;for(int i=n;i;--i){pnt[i].next=pos[a[i]]-1;pos[a[i]]=i;}for(int i=n;i;--i)pnt[i].i=i;for(int i=n;i;--i)point[i]=(PS){i,pnt[i].next};sort(pnt+1,pnt+n+1);build(root[0],1,n,0);for(int i=n;i;--i)pos[point[i].x]=i;for(int i=1,j=1;i<=n;++i){//printf("---%d---\n",i);root[i]=root[i-1];for(;pnt[j].last==i;++j){//printf("%d ",pnt[j].i);add(root[i],1,n,pos[pnt[j].i],a[pnt[j].i]);}//puts("");}//cout<<ktot<<endl;int l,r;while(m--){in(l),in(r);l=(l+lastans)%n+1,r=(r+lastans)%n+1;if(l>r)swap(l,r);lastans=0;query(root[l],l,r,r,n);printf("%d\n",lastans);}
}

总结:
①我们可以把每个数看成点,也可以把询问看成点,这两种方式效果是不一样的,要都想一想。

这篇关于[bzoj3489] A simple rmq problem 解题报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/795248

相关文章

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

开题报告中的研究方法设计:AI能帮你做什么?

AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 大家都准备开题报告了吗?研究方法部分是不是已经让你头疼到抓狂? 别急,这可是大多数人都会遇到的难题!尤其是研究方法设计这一块,选定性还是定量,怎么搞才能符合老师的要求? 每次到这儿,头脑一片空白。 好消息是,现在AI工具火得一塌糊涂,比如ChatGPT,居然能帮你在研究方法这块儿上出点主意。是不

【干货分享】基于SSM的体育场管理系统的开题报告(附源码下载地址)

中秋送好礼 中秋佳节将至,祝福大家中秋快乐,阖家幸福。本期免费分享毕业设计作品:《基于SSM的体育场管理系统》。 基于SSM的体育场管理系统的开题报告 一、课题背景与意义 随着全民健身理念的深入人心,体育场已成为广大师生和社区居民进行体育锻炼的重要场所。然而,传统的体育场管理方式存在诸多问题,如资源分配不均、预约流程繁琐、数据统计不准确等,严重影响了体育场的使用效率和用户体验。

[SWPUCTF 2021 新生赛]web方向(一到六题) 解题思路,实操解析,解题软件使用,解题方法教程

题目来源 NSSCTF | 在线CTF平台因为热爱,所以长远!NSSCTF平台秉承着开放、自由、共享的精神,欢迎每一个CTFer使用。https://www.nssctf.cn/problem   [SWPUCTF 2021 新生赛]gift_F12 这个题目简单打开后是一个网页  我们一般按F12或者是右键查看源代码。接着我们点击ctrl+f后快速查找,根据题目给的格式我们搜索c