HDOJ6483 A Sequence Game #线段树 树状数组 离线操作#

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.

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].

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.

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

liuyiding   |   We have carefully selected several similar problems for you:  6742 6741 6740 6739 6738

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;
}

猜你喜欢

转载自blog.csdn.net/qq_35850147/article/details/104316792