Sequence II
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 4734 Accepted Submission(s): 1329
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
给你n(n≤2e5)个数,每个数的大小0<Ai≤2e5。再给你m(m≤2e5)个询问。对于每个询问输入l,r,表示Al...Ar这个区间我们得到每个数第一次出现的位置下标的排列,假设这个区间有k个不同的数,我们得到的每个数第一次出现的位置的排列是p1<p2<p3<...<pk,叫你求第(k+1)/2这个数是多少?
从右往左建主席树,维护每个数第一次出现的位置,对于每次l,r来说,查询T[l]状态下l,r区间内共有多少个第一次出现的位置,然后查询(sum+1)/2个就行了
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 200010;
const int M = MAXN * 40;
int tot, a[MAXN];
int T[M], lson[M], rson[M], c[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 m) {
int newroot = tot++, tmp = newroot;
c[newroot] = c[root] + val;
int l = 1, r = m;
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 {
rson[newroot] = tot++; lson[newroot] = lson[root];
newroot = rson[newroot]; root = rson[root];
l = mid + 1;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int query(int root, int l, int r, int k) {
if (l == r)return l;
int mid = (l + r) >> 1;
if (c[lson[root]] >= k) {
r = mid;
return query(lson[root], l, r, k);
}
else {
l = mid + 1;
k -= c[lson[root]];
return query(rson[root], l, r, k);
}
}
int querysum(int root, int l, int r, int L, int R) {
if (L <= l && r <= R) {
return c[root];
}
int mid = (l + r) >> 1, sum = 0;
if (L <= mid) {
sum += querysum(lson[root], l, mid, L, R);
}
if (R > mid) {
sum += querysum(rson[root], mid + 1, r, L, R);
}
return sum;
}
int pos[MAXN];
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int te; cin >> te;
int cas = 1;
while (te--) {
memset(pos, 0, sizeof pos);
int n, m; cin >> n >> m;
tot = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
T[n + 1] = build(1, n);
for (int i = n; i >= 1; i--) {
T[i] = update(T[i + 1], i, 1, n);
if (pos[a[i]] != 0)T[i] = update(T[i], pos[a[i]], -1, n);
pos[a[i]] = i;
}
cout << "Case #" << cas << ":";
int laans = 0;
while (m--) {
int l, r;
cin >> l >> r;
l = (l + laans) % n + 1;
r = (r + laans) % n + 1;
if (l > r)swap(l, r);
int k = querysum(T[l], 1, n, l, r);
k = (k + 1) / 2;
laans = query(T[l], 1, n, k);
cout << " " << laans;
}
cas++;
cout << "\n";
}
return 0;
}