zoukankan      html  css  js  c++  java
  • hdu5172 GTY's gay friends

    传送门
    给出一个序列,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
    ");
                    else printf("NO
    ");
                }else printf("NO
    ");
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    msp430入门学习21--TA
    msp430入门学习20
    msp430入门学习17
    msp430入门学习16
    msp430入门学习15--时钟
    msp430入门学习14
    msp430入门学习13
    msp430入门学习12
    msp430入门学习11
    msp430入门学习10
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13661841.html
Copyright © 2011-2022 走看看