题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3489

题意:一个数列。每次询问一个区间内出现一次的最大的数字是多少。

思路:设last[i]表示i位置的数字上一次出现的位置,next[i]类似。那么询问区间[L,R]时,这个区间的哪些数字可以只出现一次呢?是那些last值小于L且next值大于R的数字。因此按照last排序后,按照last可持久化。具体看代码吧 不好说

const int N=100005;

struct node
{
int val,last,next,id;
}; node b[N];
int last[N],next[N],n,m; struct Node1
{
int Max;
int L,R;
}; struct Node2
{
int root;
int L,R;
}; Node1 A[40000005];
Node2 a[N*20];
int ANum,aNum; int cmp(node a,node b)
{
return a.last<b.last;
} int root[N]; void insert1(int &t,int L,int R,int pos,int val)
{
int cur=++ANum;
A[cur]=A[t];
t=cur;
A[t].Max=max(A[t].Max,val); if(L==R) return; int M=(L+R)>>1;
if(pos<=M) insert1(A[t].L,L,M,pos,val);
else insert1(A[t].R,M+1,R,pos,val);
} void insert(int &t,int L,int R,int posX,int posY,int val)
{
int cur=++aNum;
a[cur]=a[t];
t=cur;
insert1(a[t].root,1,n,posY,val);
if(L==R) return;
int M=(L+R)>>1;
if(posX<=M) insert(a[t].L,L,M,posX,posY,val);
else insert(a[t].R,M+1,R,posX,posY,val);
} int query1(int t,int L,int R,int ll,int rr)
{
if(!t) return 0;
if(L==ll&&R==rr) return A[t].Max;
int M=(L+R)>>1;
if(rr<=M) return query1(A[t].L,L,M,ll,rr);
if(ll>M) return query1(A[t].R,M+1,R,ll,rr);
int ans1=query1(A[t].L,L,M,ll,M);
int ans2=query1(A[t].R,M+1,R,M+1,rr);
return max(ans1,ans2);
} int query(int t,int L,int R,int ll,int rr,int ll1,int rr1)
{
if(L==ll&&R==rr) return query1(a[t].root,1,n,ll1,rr1);
int M=(L+R)>>1;
if(rr<=M) return query(a[t].L,L,M,ll,rr,ll1,rr1);
if(ll>M) return query(a[t].R,M+1,R,ll,rr,ll1,rr1);
int ans1=query(a[t].L,L,M,ll,M,ll1,rr1);
int ans2=query(a[t].R,M+1,R,M+1,rr,ll1,rr1);
return max(ans1,ans2);
} int main()
{
//FFF; n=getInt(); m=getInt();
int i;
for(i=1;i<=n;i++) b[i].val=getInt(),b[i].id=i,last[i]=0,next[i]=n+1;
for(i=1;i<=n;i++)
{
b[i].last=last[b[i].val];
last[b[i].val]=i;
}
for(i=n;i>=1;i--)
{
b[i].next=next[b[i].val];
next[b[i].val]=i;
}
sort(b+1,b+n+1,cmp);
int j=1;
for(i=0;i<n;i++)
{
if(i) root[i]=root[i-1];
while(j<=n&&b[j].last==i)
{
insert(root[i],0,n+1,b[j].next,b[j].id,b[j].val);
j++;
}
} int ans=0;
while(m--)
{
int L=getInt();
int R=getInt();
L=(L+ans)%n+1;
R=(R+ans)%n+1;
if(L>R) swap(L,R);
ans=query(root[L-1],0,n+1,R+1,n+1,L,R);
printf("%d\n",ans);
}
}

BZOJ 3489 A simple rmq problem(可持久化线段树)的更多相关文章

  1. BZOJ 3489 A simple rmq problem 可持久化KDtree/二维线段树

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题意概述: 给出一个序列,每次询问一个序列区间中仅出现了一次的数字最大是多少,如果 ...

  2. bzoj 3489: A simple rmq problem k-d树思想大暴力

    3489: A simple rmq problem Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 551  Solved: 170[Submit][ ...

  3. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

  4. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

  5. bzoj 3489 A simple rmq problem - 线段树

    Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直 ...

  6. bzoj 3489 A simple rmq problem——主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  7. bzoj 3489 A simple rmq problem —— 主席树套线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...

  8. BZOJ 3489: A simple rmq problem (KD-tree做法)

    KD树水过这道可持久化树套树-其实就是个三维偏序 题解戳这里 CODE #include <bits/stdc++.h> using namespace std; #define ls ( ...

  9. BZOJ.3489.A simple rmq problem(主席树 Heap)

    题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...

随机推荐

  1. json和字符串/数组/集合的互相转换の神操作总结

    一:前端字符串转JSON的4种方式 1,eval方式解析,恐怕这是最早的解析方式了. function strToJson(str){ var json = eval('(' + str + ')') ...

  2. 夺命雷公狗---微信开发54----微信js-sdk接口开发(1)之快速入门

    js-sdk基本介绍 除去服务号的九大接口外,微信提供了JS-SDK接口,所谓JS-SDK接口也就是在网页中使用javascript来更改网页设置, (比如隐藏右上角的菜单)获取用户状态(比如地理位置 ...

  3. java 网络编程(二)----UDP基础级的示例

    下面介绍UDP基础级的代码示例: 首先了解创建UDP传输的发送端的思路: 1.创建UDP的Socket服务.2.将要发送的数据封装到数据包中.3.通过UDP的socket服务将数据包发送出去.4.关闭 ...

  4. Android学习参考

    收到一些朋友的微博私信,说能不能给Android新手们一些指导,我只能说指导谈不上,毕竟我也很多东西正在学习中,与此同时一大学同学准备转行Android,可以说是从头开始,那么我就姑且以一个过来人的身 ...

  5. Gson将参数放入实体类中进行包装之后再传递

    package com.sinoservices.dms.orderinfo.entity; public class OrderDetailKeyCondition { //工单主键 private ...

  6. [PHP100] PHP如何防止注入及开发安全

    1.PHP注入的基本原理 程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对 用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据 库查询代码,根据程序返回 ...

  7. 用C#.NET编写软件注册机

    验证注册码是保护软件产品产权的常用手段.一般过程如下, 1.  软件发行者收集用户特有的信息: 2.  根据用户特有的信息,使用注册机生成注册码并把注册码发给客户: 3.  向软件导入注册码,由软件自 ...

  8. Oracle找出非数字

    可以这样判断: select translate('99999999999999', '\1234567890', '\') from dual; 返回的是空 ​ select translate(' ...

  9. Android 读取Assets中资源

    //读取文件 private static String getFromAssets(Context context, String fileName) { String result = " ...

  10. js笔记---拖动元素

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...