bzoj 3489 A simple rmq problem——主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489
题解:http://www.itdaan.com/blog/2017/11/24/9bc46b690756fe252e17fc3ca90aa01.html
所以就没写KD-tree、树套堆、分块,而是写了树套树。
限制条件是:pr<L;nt>R;L<= i <=R。
对pr排序后建主席树,调用1~L-1的主席树就能限制好第一个条件;主席树里维护 nt 的值域,调用R+1~n+1的部分就能限制好第二个条件;因为有第三个条件,所以每个点上带一个线段树,维护 i 的位置,记录max值,就行了。
调了半天原来是读入理解错了;1A好高兴。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+5,M=N*20,M2=M*20; int n,m,tot,tt2,pre[N],rt[N],ans; struct Node{int pr,i,nt,c; }a[N]; struct Tr{int ls,rs,rt; }tr[M]; struct T{int ls,rs,mx; }t[M2]; int rdn() {int ret=0;bool fx=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();return fx?ret:-ret; } bool cmpl(Node u,Node v){return u.pr<v.pr;} void insert(int &cr,int pre,int l,int r,Node k) {cr=++tt2; t[cr].ls=t[pre].ls; t[cr].rs=t[pre].rs;t[cr].mx=max(t[pre].mx,k.c);// printf(" bdin: l=%d r=%d mx=%d\n",l,r,t[cr].mx);if(l==r) return;int mid=l+r>>1;if(k.i<=mid) insert(t[cr].ls,t[pre].ls,l,mid,k);else insert(t[cr].rs,t[pre].rs,mid+1,r,k); } void build(int &cr,int pre,int l,int r,Node k) {cr=++tot; tr[cr].ls=tr[pre].ls; tr[cr].rs=tr[pre].rs;insert(tr[cr].rt,tr[pre].rt,1,n,k); // printf("bdout: l=%d r=%d rt=%d\n",l,r,tr[cr].rt);if(l==r) return; int mid=l+r>>1;if(k.nt<=mid) build(tr[cr].ls,tr[pre].ls,l,mid,k);else build(tr[cr].rs,tr[pre].rs,mid+1,r,k); } int find(int x) {int l=1,r=n,ret=0;while(l<=r){int mid=l+r>>1;if(a[mid].pr<=x)ret=mid,l=mid+1;else r=mid-1;}return ret; } int query(int cr,int l,int r,int L,int R) {if(!cr) return 0; // printf(" qin: l=%d r=%d(L=%d R=%d)\n",l,r,L,R);if(l>=L&&r<=R) return t[cr].mx;int mid=l+r>>1,ret=0;if(L<=mid) ret=query(t[cr].ls,l,mid,L,R);if(mid<R) ret=max(ret,query(t[cr].rs,mid+1,r,L,R)); // printf(" qin: l=%d r=%d ret=%d\n",l,r,ret);return ret; } int query(int cr,int l,int r,int L,int R,int ql,int qr) {if(!cr)return 0; // printf("qout: l=%d r=%d rt=%d(L=%d R=%d)\n", // l,r,tr[cr].rt,L,R);if(l>=L&&r<=R) return query(tr[cr].rt,1,n,ql,qr);int mid=l+r>>1,ret=0;if(L<=mid) ret=query(tr[cr].ls,l,mid,L,R,ql,qr);if(mid<R) ret=max(ret,query(tr[cr].rs,mid+1,r,L,R,ql,qr)); // printf("qout: l=%d r=%d ret=%d\n",l,r,ret);return ret; } int main() {n=rdn(); m=rdn();for(int i=1,d;i<=n;i++){d=rdn(); a[i].pr=pre[d];a[i].i=i; a[i].c=d; pre[d]=i;}for(int i=1;i<=n;i++) pre[i]=n+1;for(int i=n;i;i--)a[i].nt=pre[a[i].c],pre[a[i].c]=i;sort(a+1,a+n+1,cmpl);for(int i=1;i<=n;i++)build(rt[i],rt[i-1],1,n+1,a[i]);for(int i=1,l,r,x,y,k;i<=m;i++){x=rdn(); y=rdn();l=min((x+ans)%n+1,(y+ans)%n+1);r=max((x+ans)%n+1,(y+ans)%n+1);k=find(l-1);// printf("st: l=%d r=%d k=%d\n",l,r,k); ans=query(rt[k],1,n+1,r+1,n+1,l,r);printf("%d\n",ans);}return 0; }
转载于:https://www.cnblogs.com/Narh/p/9719242.html
bzoj 3489 A simple rmq problem——主席树套线段树相关推荐
- BZOJ 3489: A simple rmq problem
3489: A simple rmq problem Time Limit: 40 Sec Memory Limit: 600 MB Submit: 1594 Solved: 520 [Submi ...
- BZOJ 3489: A simple rmq problem(K-D Tree)
Time Limit: 40 Sec Memory Limit: 512 MB Submit: 2579 Solved: 888 [Submit][Status][Discuss] Descrip ...
- 模板:二维线段树(线段树套线段树)
文章目录 问题 解析 单点修改 询问 完整代码 标记永久化 代码 所谓二维线段树,就是有两个维度的线段树 (逃) 问题 给出一个矩形 要求支持以下操作: 1.询问一个子矩形的最值 2.修改某一个单点的 ...
- 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们 ...
- 【BZOJ】3339: Rmq Problem 3585: mex(线段树+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!! ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)
题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...
- BZOJ3489 A simple rmq problem 【可持久化树套树】*
BZOJ3489 A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一 ...
- 【BZOJ3489】A simple rmq problem kd-tree
[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...
最新文章
- 稳~阿里程序员常用的 15 款开发者工具
- COMP0037 Coursework Investigating Path Planning Algorithms
- 最长上升子序列(LIS)长度
- python 非线性多项式拟合_用python进行非线性回归-有什么简单的方法可以更好地拟合这些数据?...
- 有意思:textarea resize属性下纯CSS交互效果
- 找图点击-找图自动点击全能模拟王软件
- sockscap on linux: wsocks
- 测试环境搭建-7:安装loadrunner提示此计算机上缺少vc2005_sp1_with_atl_fix_redist解决方法
- 好书推荐|《CSS新世界》,前端人员必备宝书!
- 在Android中Unity3D透明背景的实现
- Python3爬虫与多线程
- 【行业聚焦】畅捷通用自然语言技术颠覆企业应用人机交互模式!
- 苹果开发者账号--关于邓白氏编码的申请
- java并发--活动对象
- 一加7使用adb强制90hz时遇到的问题
- Java架构师-容器化(一):服务容器化技术-Docker、Cloud Foundry
- SVM中KKT条件介绍
- 2021乐平四中高考成绩查询,喜报!乐平高考成绩出炉!2019再创佳绩!!
- python自定义事件event的含义_事件Event详解
- 计算机导论——多媒体技术04