【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=5919

【题目大意】

  给出一个数列,每次查询数列中,区间非重元素的下标的中位数。查询操作强制在线。

【题解】

  因为查询的是下标,因此,我们直接在下标操作表示这里有没有数字,然后查询k大数即可,非重元素即需要在区间每个数第一次出现的地方+1,然后对处理完的区间进行查询即可,考虑到查询强制在线,不能扫描线,因此只能建立可持久化线段树,线段树的第i个版本表示第i个位置往后的每个元素第一次出现的位置,那么查询区间【L,R】,就是查询第L个版本的线段树第k大数,然后对于k的计算,我们只要在第L个版本的线段树上查询区间【L,R】中的非重元素个数,即线段树求和,之后除2上取整即可。

【代码】

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200010;
int n,m,i,x,y,z,ans;
int l[N*40],r[N*40],v[N*40],tot,root[N],a[N],pre[N];
void read(int&a){
char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
}
int build(int a,int b){
int x=++tot; v[x]=0;
if(a==b)return x;
int mid=(a+b)>>1;
return l[x]=build(a,mid),r[x]=build(mid+1,b),x;
}
int change(int x,int a,int b,int c,int p){
int y=++tot;v[y]=v[x]+p;
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)l[y]=change(l[x],a,mid,c,p),r[y]=r[x];
else l[y]=l[x],r[y]=change(r[x],mid+1,b,c,p);
return y;
}
int query(int x,int a,int b,int L,int R){
if(L<=a&&b<=R)return v[x];
int mid=(a+b)/2,res=0;
if(L<=mid)res+=query(l[x],a,mid,L,R);
if(R>mid)res+=query(r[x],mid+1,b,L,R);
return res;
}
int getans(int x,int a,int b,int k){
if(a==b)return a;
int mid=(a+b)>>1;
if(v[l[x]]>=k)return getans(l[x],a,mid,k);
else return getans(r[x],mid+1,b,k-v[l[x]]);
}int T,Cas=0;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);tot=0;
memset(pre,-1,sizeof(pre));
for(int i=1;i<=n;i++)read(a[i]);
root[n+1]=build(1,n);
for(int i=n;i;i--){
if(pre[a[i]]==-1)root[i]=change(root[i+1],1,n,i,1);
else{
int tmp=change(root[i+1],1,n,pre[a[i]],-1);
root[i]=change(tmp,1,n,i,1);
}pre[a[i]]=i;
}printf("Case #%d:",++Cas);
int ans=0;
while(m--){
read(x);read(y);
int xx=(x+ans)%n+1,yy=(y+ans)%n+1;
x=min(xx,yy);y=max(xx,yy);
int u=query(root[x],1,n,x,y);
u=(u+1)/2;
ans=getans(root[x],1,n,u);
printf(" %d",ans);
}puts("");
}return 0;
}

HDU 5919 Sequence II(可持久化线段树)的更多相关文章

  1. HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)

    HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...

  2. HDU 5919 Sequence II(主席树+逆序思想)

    Sequence II Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  3. HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...

  4. HDU 5919 Sequence II 主席树

    Sequence II Problem Description   Mr. Frog has an integer sequence of length n, which can be denoted ...

  5. HDU 5919 Sequence II(主席树)题解

    题意:有A1 ~ An组成的数组,给你l r,L = min((l + ans[i - 1]) % n + 1, (r + ans[i - 1]) % n + 1),R = max((l + ans[ ...

  6. hdu 5919 Sequence II (可持久化线段树)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 大致题意: 给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算 ...

  7. HDU 5919 -- Sequence II (主席树)

    题意: 给一串数字,每个数字的位置是这个数第一次出现的位置. 每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...

  8. HDU - 5919 Sequence II

    题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...

  9. HDU 3397 Sequence operation 多标记线段树

    /* 一开始维护了两个标记 开了两个数组 想的是 可能当前两种操作都要做 但是太复杂了 不好处理 其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是 ...

随机推荐

  1. LNMP卸载

    先停掉所有服务 service mysql stop service php-fpm stop service nginx stop killall mysql* killall php-fpm* k ...

  2. < meta > 元素 概要

    < meta > 元素 概要 标签提供关于HTML文档的元数据.元数据不会显示在页面上,但是对于机器是可读的.它可用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他 we ...

  3. codeforces 645E . Intellectual Inquiry

    题目链接 如果不考虑重复的元素, 那么我们可以很容易的发现, 长度为n的字符串它的子串数量是 $ 2^n $ . 我们设每个到位置i, 答案的数量为f[i]. 然后我们考虑重复的, 我们发现, 每加入 ...

  4. JDBC笔记

    简介 JDBC是Java规定的访问数据库的API,目前主流的数据库都支持JDBC.使用JDBC访问不同的数据库时需要安装不同的驱动. JDBC定义了数据库的链接,SQL语句的执行以及查询结果集的遍历等 ...

  5. maintenance ShellScripts

    1.Linux挂载Winodws共享文件夹 2.查看http的并发请求数及其TCP连接状态: 3.用tcpdump嗅探80端口的访问看看谁最高 4.统计/var/log/下文件个数 5.查看当前系统每 ...

  6. 面向对象程序设计-C++_课时12访问限制

    private: 只有这个类(相同的类,不同的对象也可以)的成员函数可以访问这些成员变量或函数 public: 任何人都可以访问 protected: 只有这个类以及它的子子孙孙可以访问

  7. 使用iscroll插件实现下拉刷新功能

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. Neo4j数据库简单

    作为世界上先进的地图数据库,Neo4j如今,公司已成为许多互联网的首选.Neo4j它是基于java开源地图数据库开发,另外一个NoSQL数据库.Neo4j在保证对数据关系的良好刻画的同一时候.还支持传 ...

  9. onclick=‘’return false“

    文章来自  http://www.cnblogs.com/hellen-li/archive/2010/10/22/1858422.html checkbox没有readOnly属性,可以这样让它保持 ...

  10. sql中复合组建解析

    每个表只能有一个主键 唯一键/约束可以多个 复合主键是指复合唯一,比如: 1 1 1 2 2 1 2 2 单看任何一列都不是唯一,但组合起来就是唯一的. Create Table 表名 (字段名1 I ...