题意:有A1 ~ An组成的数组,给你l r,L = min((l + ans[i - 1]) % n + 1, (r + ans[i - 1]) % n + 1),R = max((l + ans[i - 1]) % n + 1, (r + ans[i - 1]) % n + 1),你先需要的到L,R区间有k个不同的数字,然后问你L,R区间第(k + 1)/ 2个不同的数字下标是多少?

思路:显然是个在线询问。

我们之前已经会用主席树求区间内有多少不同数字了:从左到右把每个数字的位置存进每个操作的线段树,如果之前这个数已经出现,就在当前这棵线段树中删掉之前出现的位置,以保证每个数字出现的唯一性。显然每个区间保存的是某个数字最右边出现的位置。

但是这里显然我们不能去直接求第(k + 1)/ 2个不同的数字下标,因为我这里要求的是最早出现第(k + 1)/ 2个数的位置。那我直接从n往1建主席树,那我就变成了每个区间保存的是某个数字最左边出现的位置,显然我第i棵树并没有保存i前面的位置,那我就可以直接求i到后面任意位置的区间的第p个不相同数出现的位置。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + ;
const int M = maxn * ;
const ull seed = ;
const int INF = 0x3f3f3f3f;
const int MOD = ;
int a[maxn], root[maxn], tot;
int n, q;
struct node{
int lson, rson;
int sum;
}T[maxn * ];
int fa[maxn], ans[maxn];
void init(){
tot = ;
memset(fa, -, sizeof(fa));
memset(T, , sizeof(T));
}
void update(int l, int r, int &now, int pre, int pos, int v){
T[++tot] = T[pre], now = tot;
T[now].sum += v;
if(l == r) return;
int m = (l + r) >> ;
if(pos <= m)
update(l, m, T[now].lson, T[pre].lson, pos, v);
else
update(m + , r, T[now].rson, T[pre].rson, pos, v);
}
int query1(int l, int r, int L, int R, int now){
if(L <= l && R >= r){
return T[now].sum;
}
int m = (l + r) >> , sum = ;
if(L <= m)
sum += query1(l, m, L, R, T[now].lson);
if(R > m)
sum += query1(m + , r, L, R, T[now].rson);
return sum;
}
int query2(int l, int r, int now, int k){
if(l == r) return l;
int m = (l + r) >> ;
int sum = T[T[now].lson].sum;
if(sum >= k)
return query2(l, m, T[now].lson, k);
else
return query2(m + , r, T[now].rson, k - sum);
}
int main(){
int ca = , t;
scanf("%d" ,&t);
while(t--){
init();
scanf("%d%d", &n, &q);
root[n + ] = ;
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
for(int i = n; i >= ; i--){
if(fa[a[i]] == -){
update(, n, root[i], root[i + ], i, );
fa[a[i]] = i;
}
else{
update(, n, root[i], root[i + ], i, );
update(, n, root[i], root[i], fa[a[i]], -);
fa[a[i]] = i;
}
}
ans[] = ;
for(int i = ; i <= q; i++){
int l, r, L, R, k;
scanf("%d%d", &l, &r);
L = min((l + ans[i - ]) % n + , (r + ans[i - ]) % n + );
R = max((l + ans[i - ]) % n + , (r + ans[i - ]) % n + );
k = query1(, n, L, R, root[L]);
ans[i] = query2(, n, root[L], (k + ) / );
}
printf("Case #%d:", ca++);
for(int i = ; i <= q; i++)
printf(" %d", ans[i]);
printf("\n");
} return ;
}

HDU 5919 Sequence II(主席树)题解的更多相关文章

  1. HDU 5919 Sequence II 主席树

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

  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个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...

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

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

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

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

  6. HDU5919 Sequence II(主席树)

    Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,anThere are ...

  7. HDU - 5919 Sequence II

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

  8. hdu 5147 Sequence II【树状数组/线段树】

    Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...

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

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

随机推荐

  1. webpack常见问题 收藏

    一:webpack认识 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依赖关 ...

  2. mysql统计库下所有表数据行数

    一.执行下面sql select concat( 'select "', TABLE_name, '", count(*) from ', TABLE_SCHEMA, '.', T ...

  3. org.hibernate.HibernateException: Duplicate identifier in table for: Waa

    提示表的标识符重复,发现是数据库中的主键id重复了.因为是序列自动生成的. 我原本以为是因为我的序列的问题,序列.nextval()有问题,但是当我在数据库测试时,发现当前序列没有问题.但是当数据插入 ...

  4. 【VIM】-NO.140.VIM.1 -【VIM】

    Style:Mac Series:Java Since:2018-09-10 End:2018-09-10 Total Hours:1 Degree Of Diffculty:5 Degree Of ...

  5. (转)测试如何区别是前端的问题还是后台的bug

    常常说到的一个IT项目,包括前端开发,后台开发,软件测试,架构,项目经理,产品需求.那么对于一位优秀的软件测试工程师来说,需要区分前端和后台的工作就显得尤为重要. - 什么是前端和后台 简而言之,前端 ...

  6. 正则表达式-----re库

    1.正则表达式的概念 a.为什么要用正则? 用字符串匹配也是可以的: startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False.如果参数 be ...

  7. 2#第一个Java程序

    好,我们来写一个最简单的Java程序: public class HelloWorld{ public static void main(String[] argc){ System.out.prin ...

  8. 全志A33编译环境搭建

    0x00 环境说明: 所使用的开发板为锐尔威视的插针版A33_Vstar 主机系统为WIN10 1809 x64,并且安装VMware Workstation Pro 下载64位的Ubuntu安装镜像 ...

  9. arcgis for JavaScript API 4.5与4.3的区别

    arcgis 4.5与4.3区别: 鉴于本人使用4.3时间比较久,而arcgis for JavaScript API于9月28日推出了4.5版本,但是直接更换4.5的init.js会出现意想不到的错 ...

  10. xpath详细讲解

    什么是XML XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 的标签需要 ...