zoukankan      html  css  js  c++  java
  • 线段树+离线 hdu5654 xiaoxin and his watermelon candy

    传送门:点击打开链接

    题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的。如今告诉你序列。然后Q次询问。每次询问一个区间[l,r],问区间里有多少个三元组满足要求

    思路:刚開始看错题目了,原来三元组是连续3个,这作为bc最后一题也太水了把。

    先一遍预处理。把连续3个满足条件的找出来,放到还有一个数组里排序去重,用这个数组来给三元组哈希。再扫一遍给三元组在之前那个排序好的数组里二分一下得到下标,大概就是哈希一下,用一个数字来表示。

    之后的查询。事实上就是。在区间内。不同的数字有多少个。

    这是一个很经典的线段树+离线的题目,仅仅要按右区间排序,然后xjb搞即可了,就不多说了。

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <cstdio>
    #include <cctype>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define fuck(x) cout<<"["<<x<<"]"
    #define FIN freopen("input.txt","r",stdin)
    #define FOUT freopen("output.txt","w+",stdout)
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    
    const int MX = 2e5 + 5;
    
    struct Data {
        int a, b, c;
        bool operator<(const Data &P) const {
            if(a == P.a) {
                if(b == P.b) return c < P.c;
                return b < P.b;
            }
            return a < P.a;
        }
        bool operator==(Data &P) const {
            return a == P.a && b == P.b && c == P.c;
        }
    } D[MX], dt;
    struct Seg {
        int l, r, id;
        bool operator<(const Seg &P) const {
            return r < P.r;
        }
    } S[MX];
    int n, Q, ans[MX];
    int sum[MX << 2], col[MX << 2];
    int A[MX], pre[MX], pos[MX], sz;
    
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    void push_up(int rt) {
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    void push_down(int rt, int len) {
        if(col[rt]) {
            int sr = len >> 1, sl = len - sr;
            col[rt << 1] += col[rt]; col[rt << 1 | 1] += col[rt];
            sum[rt << 1] += col[rt] * sl; sum[rt << 1 | 1] += col[rt] * sr;
            col[rt] = 0;
        }
    }
    void build(int l, int r, int rt) {
        sum[rt] = col[rt] = 0;
        if(l == r) return;
        int m = (l + r) >> 1;
        build(lson); build(rson);
    }
    int query(int p, int l, int r, int rt) {
        if(l == r) return sum[rt];
        int m = (l + r) >> 1;
        push_down(rt, r - l + 1);
        if(p <= m) return query(p, lson);
        else return query(p, rson);
    }
    void update(int L, int R, int l, int r, int rt) {
        if(L <= l && r <= R) {
            sum[rt] += r - l + 1;
            col[rt] += 1;
            return;
        }
        int m = (l + r) >> 1;
        push_down(rt, r - l + 1);
        if(L <= m) update(L, R, lson);
        if(R > m) update(L, R, rson);
        push_up(rt);
    }
    
    int main() {
        int T; //FIN;
        scanf("%d", &T);
        while(T--) {
            sz = 0;
            scanf("%d", &n);
            build(1, n, 1);
    
            for(int i = 1; i <= n; i++) scanf("%d", &A[i]);
            for(int i = 3; i <= n; i++) {
                if(A[i - 2] <= A[i - 1] && A[i - 1] <= A[i]) {
                    sz++;
                    D[sz].a = A[i - 2]; D[sz].b = A[i - 1]; D[sz].c = A[i];
                }
            }
            sort(D + 1, D + 1 + sz);
            sz = unique(D + 1, D + 1 + sz) - D - 1;
            for(int i = 1; i <= sz; i++) pos[i] = 0;
            for(int i = 1; i <= n; i++) {
                if(i >= 3 && A[i - 2] <= A[i - 1] && A[i - 1] <= A[i]) {
                    dt.a = A[i - 2]; dt.b = A[i - 1]; dt.c = A[i];
                    int id = lower_bound(D + 1, D + 1 + sz, dt) - D;
                    pre[i] = pos[id];
                    pos[id] = i;
                } else pre[i] = -1;
            }
    
            scanf("%d", &Q);
            for(int i = 1; i <= Q; i++) {
                S[i].id = i;
                scanf("%d%d", &S[i].l, &S[i].r);
            }
            sort(S + 1, S + 1 + Q);
    
            int cur = 1;
            for(int r = 1; r <= n; r++) {
                if(pre[r] != -1) update(pre[r] + 1, r, 1, n, 1);
                while(cur <= Q && S[cur].r == r) {
                    if(S[cur].l + 2 <= S[cur].r) ans[S[cur].id] = query(S[cur].l + 2, 1, n, 1);
                    else ans[S[cur].id] = 0;
                    cur++;
                }
            }
    
            for(int i = 1; i <= Q; i++) printf("%d
    ", ans[i]);
        }
        return 0;
    }


  • 相关阅读:
    POJ2828
    Docker容器修改端口映射
    CentOS 7使用ISO镜像配置本地yum源
    Windows 自带的 Linux 子系统
    vue富文本编辑器插件vue-quill-editor使用
    修改docker容器存放位置
    Linux 硬盘相关操作
    centos7基础相关
    ubuntu-k8s搭建
    redhat 6.6 离线docker
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7116080.html
Copyright © 2011-2022 走看看