HDU 5919 Sequence II(可持久化线段树)
【题目链接】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(可持久化线段树)的更多相关文章
- HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)
HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...
- HDU 5919 Sequence II(主席树+逆序思想)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...
- HDU 5919 Sequence II 主席树
Sequence II Problem Description Mr. Frog has an integer sequence of length n, which can be denoted ...
- 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[ ...
- hdu 5919 Sequence II (可持久化线段树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 大致题意: 给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算 ...
- HDU 5919 -- Sequence II (主席树)
题意: 给一串数字,每个数字的位置是这个数第一次出现的位置. 每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...
- HDU - 5919 Sequence II
题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...
- HDU 3397 Sequence operation 多标记线段树
/* 一开始维护了两个标记 开了两个数组 想的是 可能当前两种操作都要做 但是太复杂了 不好处理 其实 当前要做的标记可以只有一个 我们在Insert的时候 要打的标记是2即翻转区间: 1.如果原来是 ...
随机推荐
- MYSQL区分大小写
MYSQL区分大小写 1.linux下mysql安装完后是默认:区分表名的大小写,不区分列名的大小写: 2.用root帐号登录后,在/etc/my.cnf 中的[mysqld]后添加添加lower ...
- iOS对项目中第三方类库的管理——CocoaPods
http://blog.csdn.net/lengshengren/article/details/1767 唐巧的博客:http://www.devtang.com/blog/2014/05/25/ ...
- QF——OC中的KVC,KVO
KVC: (Key Value Coding) 键值编码 所谓KVC,其实就是不通过set和get方法访问对象属性,而是通过属性名字符串动态的去读取属性.KVC其实也是OC反射机制的一种运用. 之所以 ...
- javascript自定义日期函数
1.格式化日期(YYYY-MM-DD) 代码: var DateFormat = function (date) { if (!(date instanceof Date)) { date = dat ...
- mysql函数操作(3)
<?php $dbh = new PDO('mysql:dbname=testdb;host=localhost', 'mysql_user', 'mysql_pwd'); $dbh->s ...
- caffe 配置 札记
cudnn的配置 1. 安装前请去先官网下载cuDNN (cudnn-7.0-linux-x64-v3),建议安装v3,v4有些问题. 将cudnn-7.0-linux-x64-v3解压后会有两个文件 ...
- UIKit之浅析UIButton
UIButton * button =[[UIButton alloc]init]; button.backgroundColor=[UIColor redColor]; [button setTit ...
- asp.net mvc 注册中的邮箱激活功能实现(二)
邮件发送功能封装 /// <summary> /// 发送注册邮件 /// </summary> /// <param name ...
- ODI中删除数据的处理
ODI中删除数据的处理 一.前提知识:数据从源数据库向数据仓库抽取时,一般采用以下几种方式: 全抽取模式如果表的数据量较小,则可以采取全表抽取方式,以TRUNCATE/INSERT方式进行数据抽取. ...
- JQ中$(document.ready())
js中window.onload与jquery中$(document.ready())的区别 <html> <head> <script type='text/javas ...