Sequence II

Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 849    Accepted Submission(s): 204

Problem Description
Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,an There are m queries.

In the i-th query, you are given two integers li and ri. Consider the subsequence ali,ali+1,ali+2,⋯,ari.

We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as p(i)1,p(i)2,⋯,p(i)ki (in ascending order, i.e.,p(i)1<p(i)2<⋯<p(i)ki).

Note that ki is the number of different integers in this subsequence. You should output p(i)⌈ki2⌉for the i-th query.

 
Input
In the first line of input, there is an integer T (T≤2) denoting the number of test cases.

Each test case starts with two integers n (n≤2×105) and m (m≤2×105). There are n integers in the next line, which indicate the integers in the sequence(i.e., a1,a2,⋯,an,0≤ai≤2×105).

There are two integers li and ri in the following m lines.

However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to l‘i,r‘i(1≤l‘i≤n,1≤r‘i≤n). As a result, the problem became more exciting.

We can denote the answers as ans1,ans2,⋯,ansm. Note that for each test case ans0=0.

You can get the correct input li,ri from what you read (we denote them as l‘i,r‘i)by the following formula:

li=min{(l‘i+ansi−1) mod n+1,(r‘i+ansi−1) mod n+1}
ri=max{(l‘i+ansi−1) mod n+1,(r‘i+ansi−1) mod n+1}
 
Output
You should output one single line for each test case.

For each test case, output one line “Case #x: p1,p2,⋯,pm”, where x is the case number (starting from 1) and p1,p2,⋯,pm is the answer.

 
Sample Input
2
5 2
3 3 1 5 4
2 2
4 4
5 2
2 5 2 1 2
2 3
2 4
 
Sample Output
Case #1: 3 3
Case #2: 3 1

Hint

/*
hdu 5919 主席树(区间不同数的个数 + 区间第k大) problem:
给你n个数字,和m个查询.
将[l,r]之间数第一次出现的位置信息弄成一个新的数组,然后找出其中k/2大的数.(k为位置的数量) solve:
通过主席树能够找出[l,r]之间有多少个不同的数,然后利用再用一个查询找出第k大的即可.
(都是类似与线段树的操作, T[i]存的是[1,n]的信息, 尽管说的只是[i,n] ,只是[1,i-1]的还没更新而已. 所以查询的时候出了点问题) hhh-2016-10-07 16:48:19
*/
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
//#define lson i<<1
//#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a)) using namespace std; const int maxn = 200100;
const int N = maxn * 100; template<class T> void read(T&num)
{
char CH;
bool F=false;
for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p)
{
if(!p)
{
puts("0");
return;
}
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} int lson[N],rson[N],c[N];
int a[maxn],T[maxn];
int tot,n,m; int build(int l,int r)
{
int root = tot++;
c[root ] = 0;
if(l != r)
{
int mid = (l+r)>>1;
lson[root] = build(l,mid);
rson[root] = build(mid+1,r);
}
return root;
} int update(int root,int pos,int val)
{
int newroot = tot ++ ,tmp= newroot;
c[newroot] = c[root] + val;
int l = 1,r = n;
while(l < r)
{
int mid = (l + r) >> 1;
if(pos <= mid)
{
lson[newroot] = tot++;
rson[newroot] = rson[root];
newroot = lson[newroot] ;
root = lson[root];
r = mid;
}
else
{
lson[newroot] = lson[root],rson[newroot] = tot++;
newroot = rson[newroot],root = rson[root];
l = mid + 1;
}
c[newroot] = c[root] + val;
}
return tmp;
} int query(int root,int pos)
{
int cnt = 0;
int l = 1,r = n;
while(pos < r)
{
int mid = (l + r) >> 1;
if(pos <= mid)
{
root = lson[root];
r = mid;
}
else
{
cnt += c[lson[root]];
root = rson[root];
l = mid + 1;
}
}
return cnt + c[root];
} int Find(int root,int k)
{
int l = 1,r = n;
while(l <= r)
{
int mid = (l + r) >> 1;
if(l == r)
return l;
if(c[lson[root]] >= k)
{
root = lson[root];
r = mid;
}
else
{
k -= c[lson[root]];
root = rson[root];
l = mid +1 ;
}
}
} int main()
{
int t,cas = 1;
// freopen("in.txt","r",stdin);
read(t);
while(t--)
{
tot = 0;
read(n),read(m);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
T[n + 1] = build(1,n);
map<int,int> mp;
for(int i = n; i >= 1; i--)
{
if(mp.find(a[i]) == mp.end())
{
T[i] = update(T[i + 1],i,1);
}
else
{
int tp = update(T[i+1],mp[a[i]],-1);
T[i] = update(tp,i,1);
}
mp[a[i]] = i;
}
int ans = 0;
int l,r;
printf("Case #%d:",cas++);
for(int i = 1; i <= m; i++)
{
read(l),read(r);
// cout << l <<" " <<r << endl;
l = (l + ans) % n + 1;
r = (r + ans)%n + 1;
if(l > r)
swap(l,r);
int num = (query(T[l],r)+1) >> 1;
// if(!num) num = 1;
ans = Find(T[l],num);
printf(" %d",ans);
}
printf("\n");
}
return 0;
}

  

hdu 5919 主席树(区间不同数的个数 + 区间第k大)的更多相关文章

  1. HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数

    xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...

  2. Super Mario HDU 4417 主席树区间查询

    Super Mario HDU 4417 主席树区间查询 题意 给你n个数(编号从0开始),然后查询区间内小于k的数的个数. 解题思路 这个可以使用主席树来处理,因为这个很类似查询区间内的第k小的问题 ...

  3. SPOJ 3267 求区间不同数的个数

    题意:给定一个数列,每次查询一个区间不同数的个数. 做法:离线+BIT维护.将查询按右端点排序.从左到右扫,如果该数之前出现过,则将之前出现过的位置相应删除:当前位置则添加1.这样做就保证每次扫描到的 ...

  4. 主席树的各类模板(区间第k大数【动,静】,区间不同数的个数,区间<=k的个数)

    取板粗   好东西来的 1.(HDOJ2665)http://acm.hdu.edu.cn/showproblem.php?pid=2665 (POJ2104)http://poj.org/probl ...

  5. HDU 4348 主席树区间更新

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  6. SPOJ:D-query(非常规主席树求区间不同数的个数)

    Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) ...

  7. SPOJ - DQUERY (主席树求区间不同数的个数)

    题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数. 解题思路:从左向右一个一 ...

  8. HDU 6278 主席树(区间第k大)+二分

    Just h-index Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)To ...

  9. POJ 2104 HDU 2665 主席树 解决区间第K大

    两道题都是区间第K大询问,数据规模基本相同. 解决这种问题, 可以采用平方划分(块状表)复杂度也可以接受,但是实际表现比主席树差得多. 这里大致讲一下我对主席树的理解. 首先,如果对于某个区间[L,R ...

随机推荐

  1. C语言第三周作业---单层循环

    一.PTA实验作业 题目1 1.实验代码 int N = 0,i; char sex; float a[9], height; scanf("%d\n", &N); for ...

  2. Software Engineering-HW1

    title: Software Engineering-HW1 date: 2017-09-13 15:41:13 tags: HW --- 阅读随笔 在<徐宥:掉进读书的兔子洞>里面, ...

  3. C语言——第一次作业(2)

    1.写程序证明p++等价于(p)++还是等价于*(p++)? #include <stdio.h> int main() { int *p,a=5; p = &a; printf( ...

  4. Flask 视图

    写个验证用户登录的装饰器:在调用函数前,先检查session里有没有用户 from functools import wraps from flask import session, abort de ...

  5. (原创)不带模板的OLE输出EXCEL

    目前我已知的EXCEL输出方式有3种: 1.GUI_DOWNLOAD函数输出(适用于简单无格式要求的输出). 2.OLE输出(适用于对EXCEL格式输出有特殊要求的,但是因其填充数据和设置格式是基于一 ...

  6. 安装Loadrunner 11.0时,弹出缺少2.8 sp1组件--解决方案(win7)

    这是因为注册表缺少FullInstallVer和Version,归根到底是madc安装的的问题 以下是解决方法: 1.运行regedit,打开注册表,进入HKEY_LOCAL_MACHINE\SOFT ...

  7. STL之queue

    描述 使用STL中的queue,完成入队.出队.获取队首.获取队尾等基本操作. 部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码. int main() { queue<int> ...

  8. Comet之SSE(Server - Sent - Envent,服务器发送事件)

    1.SSE API 先要创建一个新的EventSource对象,并传进一个入口点: var source = new EventSource("myenvent.php"); △: ...

  9. JAVA_SE基础——32.this关键字调用本类的构造方法

    黑马程序员入学blog... 也算是学习笔记. 下面我们来看段代码: package day07; class Student{ int id; //身份证 String name; //名字 pub ...

  10. wpf研究之道——datagrid控件分页

    这是我们的datagrid分页效果图,有上一页,下一页,可以跳到任何一页.当页码比较多的时候,只显示几页,其余用点点,界面实现如下: <!--分页--> <StackPanel Or ...