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

大致题意:

给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算会得到一个区间[x,y],假设这个区间内有k个数,对k个数第一次出现的位置进行排序取第(k+1)/2个数。

思路:

看题意可知要求的是区间不同数的个数和区间第k小,强制在线,

之前正好写过求区间不同数的个数的三种解法:离线树状数组,主席树,莫队,因为这道题是强制在线,莫队和离线树状数组都不能用,这里就直接用主席树了。

题目要求各个数第一次出现的位置,那么我们只要从后向前插入,重复出现的取消之前的标记,这样维护的标记就都是当前坐标i到n区间内第一次出现的,用主席树维护下就好了。

用主席树求出区间不同数的个数num后, 直接再求区间第(num+1)/2小就好了

注意数组要开大点。。之前数组开小了 超时了

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5 + ;
#define mid int m = (l + r) >> 1
int ls[M*],rs[M*],sum[M*],root[M],a[M],vis[M],idx,ans[M],n; void init()
{
idx = ;root[n+] = ; ans[] = ;
memset(ls,,sizeof(ls));
memset(vis,,sizeof(vis));
memset(rs,,sizeof(rs));
memset(sum,,sizeof(sum));
} void update(int old,int &k,int l,int r,int p,int c){
k = ++idx;
ls[k] = ls[old]; rs[k] = rs[old];
sum[k] = sum[old] + c;
if(l == r) return ;
mid;
if(p <= m) update(ls[old],ls[k],l,m,p,c);
else update(rs[old],rs[k],m+,r,p,c);
} int query(int x,int L,int R,int l,int r){ //求区间不同数的个数
if(L <= l&&R >= r) return sum[x];
mid,ret = ;
if(L <= m) ret += query(ls[x],L,R,l,m);
if(R > m) ret += query(rs[x],L,R,m+,r);
return ret;
} int query1(int x,int l,int r,int k){ //求区间第k小
if(l == r) return l;
mid,ret = sum[ls[x]];
if(ret >= k) return query1(ls[x],l,m,k);
else return query1(rs[x],m+,r,k - ret);
} int main()
{
int t,cas = ,q,x,y;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d",&n,&q);
for(int i = ;i <= n;i ++) scanf("%d",&a[i]);
for(int i = n;i >= ;i --){
int tmp = ;
if(vis[a[i]] == ) update(root[i+],root[i],,n,i,); //添加新标记
else{
update(root[i+],tmp,,n,vis[a[i]],-); //把之前的标记清掉
update(tmp,root[i],,n,i,); //添加新标记
}
vis[a[i]] = i;
}
for(int i = ;i <= q;i ++){
scanf("%d%d",&x,&y);
x = ((x + ans[i-])%n) + ;
y = ((y + ans[i-])%n) + ;
if(x > y) swap(x,y); //倒着输入的,所以取较小的
int num = (query(root[x],x,y,,n) + ) >> ; //得到中位数是区间内第num/2小的数
ans[i] = query1(root[x],,n,num); //求区间内第(num+1)/2小的数
}
printf("Case #%d: ",cas++);
for(int i = ;i < q;i ++) printf("%d ",ans[i]);
printf("%d\n",ans[q]);
}
return ;
}

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

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

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

  2. HDU 5919 Sequence II(可持久化线段树)

    [题目链接]http://acm.hdu.edu.cn/showproblem.php?pid=5919 [题目大意] 给出一个数列,每次查询数列中,区间非重元素的下标的中位数.查询操作强制在线. [ ...

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

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

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

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

  5. HDU 5919 Sequence II 主席树

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

  6. 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[ ...

  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. js求数组的最大值--奇技淫巧和笨方法

    写这篇文章的原因 我目前做的项目很少用到算法,于是这方面的东西自然就有点儿生疏.最近的一次编码中遇到了从数组中获取最大值的需求,当时我不自觉的想到了js的sort()函数,现在想来真是有些“罪过”,当 ...

  2. 51Nod 1677 treecnt

    一道比较基础的计数题,还是一个常用的单独计算贡献的例子. 首先看题目和范围,暴力枚举肯定是不可行的,而且\(O(n\ logn)\)的算法貌似很难写. 那我们就来想\(O(n)\)的吧,我们单独考虑每 ...

  3. Qt实现软件自动更新的一种简单方法

    前言 最近在学习Qt开发上位机,想实现一个检查更新的功能,网上搜索了一大圈,发现实现过程都很复杂,关键是代码看不懂,所以就自己开发一种简单的方式来实现.实现效果如下: 点击"检查更新&quo ...

  4. 基于Ping和Telnet/NC的监控脚本案例分析

    案例一:单纯地对某些ip进行ping监控 [root@test opt]# cat /opt/hosts_ip_list 192.168.10.10 192.168.10.11 192.168.10. ...

  5. Nextcloud私有云盘在Centos7下的部署笔记

    搭建个人云存储一般会想到ownCloud,堪称是自建云存储服务的经典.而Nextcloud是ownCloud原开发团队打造的号称是“下一代”存储.初一看觉得“口气”不小,刚推出来就重新“定义”了Clo ...

  6. python实现线性规划

    python工具包scipy linprog 函数格式 scipy.optimize.linprog(c, A_ub=None, b_ub=None, A_eq=None, b_eq=None, bo ...

  7. WEEK 7:团队项目的感想

    经过了几个星期的团队协作,我们的“爬虫”有了很大的完善,我作为团队中的主DEV,在这个过程中一边工作一边阅读,也有了不少的收获. Brooks的<没有银弹>告诉我们,在软件领域,没有什么绝 ...

  8. ELF分析 实践

    分析ELF文件: 首先编写一个.c文件,并使用gcc -c xx.c -o xx.o 对其进行编译. 我在这个实践中是ELF_1.o文件. 接下来输入ls -l ELF_1.o 查看重定位文件的信息. ...

  9. java感想

    Java学起来很有趣,通过学习Java可以提高自己的逻辑能力.在学习Java期间我们做了一些程序,我们班的同学也都积极准备,完成的还不错!在做程序时,我遇到了一些难题,有时也会出现错误,时间长了弄得我 ...

  10. 剑指offer:字符串的排列

    题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: ...