A Sequence Game
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 859 Accepted Submission(s): 164
Problem Description
One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solutions for a couple of days. And then he had a surprise that he misunderstood that problem and easily figured out a solution using segment tree. Now he still wonders that solution for the misread problem.
There is a sequence with N positive integers A1,A2,...,An and M queries. Each query will give you an interval [L,R] and require an answer with YES/NO indicates that whether the numbers in this interval are continuous in its integer range.
Let us assume that the maximal number in an interval is mx and the minimal number is mi. The numbers in this interval are continuous in its integer range means that each number from mi to mx appears at least once in this interval.
There is a sequence with N positive integers A1,A2,...,An and M queries. Each query will give you an interval [L,R] and require an answer with YES/NO indicates that whether the numbers in this interval are continuous in its integer range.
Let us assume that the maximal number in an interval is mx and the minimal number is mi. The numbers in this interval are continuous in its integer range means that each number from mi to mx appears at least once in this interval.
Input
The input starts with one line contains exactly one positive integer T which is the number of test cases. And then there are T cases follow.
The first line contains two positive integers n,m which has been explained above.The second line contains positive integers A1,A2,...,An.
Then there will be m lines followed. Each line contains to positive numbers Li,Ri indicating that the ith query’s interval is [Li,Ri].
The first line contains two positive integers n,m which has been explained above.The second line contains positive integers A1,A2,...,An.
Then there will be m lines followed. Each line contains to positive numbers Li,Ri indicating that the ith query’s interval is [Li,Ri].
Output
For each test case, output m line.
Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.
Each of following m lines contains a single string “YES”/ “NO” which is the answer you have got.
Sample Input
2 3 3 3 1 2 2 3 1 3 1 2 5 3 1 2 2 4 5 1 5 1 3 3 3
Sample Output
YES YES NO NO YES YES
Hint
T=5 1<=n<=100000 1<=Ai<=10^9 1<=m<=100000 The input file is very large, so you are recommend to use scanf() and printf() for IO.Source
Recommend
Solution
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> p;
const int maxn = 1e5 + 10;
int n, m, cnt, a[maxn], c[maxn], ans[maxn];
struct node { int l, r, Max, Min; } tree[maxn << 2];
struct que { int l, r, id; };
vector<que> vec;
map<int, int> last;
inline const int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
inline int ls(int id) { return id << 1; }
inline int rs(int id) { return id << 1 | 1; }
void push_up(int id)
{
tree[id].Max = max(tree[ls(id)].Max, tree[rs(id)].Max);
tree[id].Min = min(tree[ls(id)].Min, tree[rs(id)].Min);
}
void build(int id, int l, int r)
{
if ((tree[id].l = l) == (tree[id].r = r))
{
tree[id].Max = tree[id].Min = a[++cnt];
return;
}
int mid = (l + r) >> 1;
build(ls(id), l, mid);
build(rs(id), mid + 1, r);
push_up(id);
}
int getMax(int id, int l, int r)
{
if (tree[id].l == l && tree[id].r == r) return tree[id].Max;
int mid = (tree[id].l + tree[id].r) >> 1;
if (r <= mid) return getMax(ls(id), l, r);
if (l > mid) return getMax(rs(id), l, r);
return max(getMax(ls(id), l, mid), getMax(rs(id), mid + 1, r));
}
int getMin(int id, int l, int r)
{
if (tree[id].l == l && tree[id].r == r) return tree[id].Min;
int mid = (tree[id].l + tree[id].r) >> 1;
if (r <= mid) return getMin(ls(id), l, r);
if (l > mid) return getMin(rs(id), l, r);
return min(getMin(ls(id), l, mid), getMin(rs(id), mid + 1, r));
}
int lowbit(int x) { return x & -x; }
void update(int p, int v) { for (int i = p; i <= n; i += lowbit(i)) c[i] += v; }
int getSum(int p)
{
int res = 0;
for (int i = p; i > 0; i -= lowbit(i)) res += c[i];
return res;
}
bool cmp(const que& a, const que& b) { return a.r < b.r; }
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
cnt = 0;
vec.clear();
last.clear();
memset(c, 0, sizeof(c));
n = read(); m = read();
for (int i = 1; i <= n; i++) a[i] = read();
build(1, 1, n);
for (int i = 1; i <= m; i++)
{
int l = read(), r = read();
vec.push_back(que{ l, r, i });
}
sort(vec.begin(), vec.end(), cmp);
int now = 1;
for (auto q : vec)
{
for (int i = now; i <= q.r; i++)
{
if (last.count(a[i])) update(last[a[i]], -1);
last[a[i]] = i;
update(i, 1);
}
now = q.r;
int dif = getMax(1, q.l, q.r) - getMin(1, q.l, q.r);
int unq = getSum(q.r) - getSum(q.l - 1);
ans[q.id] = dif + 1 == unq;
}
for (int i = 1; i <= m; i++) printf("%s\n", ans[i] ? "YES" : "NO");
}
return 0;
}