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[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(主席树)题解的更多相关文章
- 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(主席树+逆序思想)
Sequence II Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- HDU 5919 -- Sequence II (主席树)
题意: 给一串数字,每个数字的位置是这个数第一次出现的位置. 每个询问对于序列的一个子区间,设一共有k个不同的数,求第ceil(k/2)个数的位置. 因为强制在线,所以离线乱搞pass掉. 主席树可解 ...
- HDU 5919 - Sequence II (2016CCPC长春) 主席树 (区间第K小+区间不同值个数)
HDU 5919 题意: 动态处理一个序列的区间问题,对于一个给定序列,每次输入区间的左端点和右端点,输出这个区间中:每个数字第一次出现的位子留下, 输出这些位子中最中间的那个,就是(len+1)/2 ...
- hdu 5919 Sequence II (可持久化线段树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 大致题意: 给你一个长度为n的序列,q个询问,每次询问是给你两个数x,y,经过与上一次的答案进行运算 ...
- HDU5919 Sequence II(主席树)
Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,anThere are ...
- HDU - 5919 Sequence II
题意: 给定长度为n的序列和q次询问.每次询问给出一个区间(L,R),求出区间内每个数第一次出现位置的中位数,强制在线. 题解: 用主席树从右向左的插入点.对于当前点i,如果a[i]出现过,则把原位置 ...
- hdu 5147 Sequence II【树状数组/线段树】
Sequence IITime Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- HDU 5919 Sequence II(主席树+区间不同数个数+区间第k小)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5919 题意:给出一串序列,每次给出区间,求出该区间内不同数的个数k和第一个数出现的位置(将这些位置组 ...
随机推荐
- IDEA中创建maven项目后解决main文件夹下目录不全的问题
IDEA创建maven-archetype-webapp项目的时候,创建完成后发现在main文件夹下没有java,resource等源文件夹. 解决方法: 1.选择File->Project S ...
- Copy & XCopy
1):copy不能在有子目录存在的文件中拷贝文件的同时重命名此文件名(注:这里C:为根目录,bat为子目录),而xcopy能,不过会出现提示,当然你可以加参数而不使它提示. C:\>copy c ...
- react学习过程中遇到的错误记录
1.App.js的代码如下: import React, { Component } from 'react'; import Test from './components/Test.jsx'; i ...
- opencart3图片Google Merchant Center验证通过不了的解决方法
最近在做一个opencart项目,有对接Google Merchant Center,但是一直提示产品图片验证无法通过,ytkah看了一下图片路径,/image/cache/catalog/demo/ ...
- Python3学习之路~7.3 反射
python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,该四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...
- Appium IOS 使用多模拟器并发执行测试
申明一下 转载请注明出处 复制粘贴请滚蛋 !!!!!!!! 最近在是用appium进行app的并发测试,并且Android已经实现在同一台PC机使用多个模拟器并发测试的功能 这里说一句模拟器使 ...
- C# 字典Dictionary
Dictionary<TKey, TValue> 泛型类提供了从一组键到一组值的映射.通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictionary<TKey, T ...
- 【LeetCode每天一题】Set Matrix Zeroes(设置0矩阵)
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Exampl ...
- Jsoup解析XML
先导入jsoup.jar 包 方法1:不推荐,了解即可 方法 方法3: 后期学习主流
- crypto++
CryptoPP库是一个C++书写的加密算法库,很棒. 在如今的抛却数字证书体系下,只关注公私钥对的情况下,我认为存粹的加解密算法库很有市场,虽然我以前觉得PolarSSL的加解密算法实现不错,但不影 ...