码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5172 GTY's gay friends - 线段树查询区间数字是否只出现一次

时间:2020-09-18 00:02:53      阅读:30      评论:0      收藏:0      [点我收藏+]

标签:main   struct   string   eof   str   tree   ret   长度   uil   

给出一个序列,m个查询,每次查询区间是否是\([1, r - l + 1]\)的排列
判断是否是排列:

  • 即每个数字只出现一次
  • 区间和是\(\frac{n * (n + 1)}{2}\),n是区间长度。

判断每个数字是否只出现一次,可以预处理每个数之和第一次出现这个数字的位置,如果没有那么设置为0,然后用线段树取查询区间最小值,如果是0或者比查询的右区间还打,那么这个区间里的数字只出现了一次。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define ll long long
using namespace std;
const int N = 1e6 + 5;
int Next[N];
int a[N];
ll pre[N];
int n, m;
struct TREE{
    int l, r, MA;
    #define l(p) tree[p].l
    #define r(p) tree[p].r
    #define lson(p) p << 1
    #define rson(p) p << 1 | 1
    #define MA(p) tree[p].MA
} tree[N << 2];
void pushup(int p){
    MA(p) = min(MA(lson(p)), MA(rson(p)));
}
void build(int p, int l, int r) {
    l(p) = l, r(p) = r;
    if(l == r) {
        MA(p) = Next[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(lson(p), l, mid);
    build(rson(p), mid + 1, r);
    pushup(p);
}
int query(int p, int l, int r){
    if(l <= l(p) && r(p) <= r) {
        return MA(p);
    }
    int mid = (l(p) + r(p)) >> 1;
    int ans = n + 1;
    if(l <= mid) ans = min(ans, query(lson(p), l, r));
    if(r > mid) ans = min(ans, query(rson(p), l , r));
    return ans;
}
int vis[N];
int main(){
    while(scanf("%d%d", &n, &m) != EOF) {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            pre[i] = pre[i - 1] + a[i];
            Next[i] = i;
            vis[a[i]] = 0;
        }
        for(int i = n; i >= 1; i--) {
            if(vis[a[i]] != 0) Next[i] = vis[a[i]];
            else Next[i] = n + 1;
            vis[a[i]] = i;
        }
        build(1, 1, n);
        for(int i = 1; i <= m; i++) {
            int l, r;
            scanf("%d%d", &l, &r);
            ll now = pre[r] - pre[l - 1];
            int num = (r - l + 1);
            if(now == (1ll *  num * (1 + num) / 2)){
                int pos = query(1, l, r);
                if(pos > r) printf("YES\n");
                else printf("NO\n");
            }else printf("NO\n");
        }
    }
    return 0;
}

hdu5172 GTY's gay friends - 线段树查询区间数字是否只出现一次

标签:main   struct   string   eof   str   tree   ret   长度   uil   

原文地址:https://www.cnblogs.com/Emcikem/p/13661841.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!