线段树+离线 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\n", ans[i]);
    }
    return 0;
}
时间: 2024-10-10 07:59:28

线段树+离线 hdu5654 xiaoxin and his watermelon candy的相关文章

【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)

pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon candy Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 233    Accepted Submission(s): 61 Problem Des

HDU 5654 xiaoxin and his watermelon candy 离线树状数组

xiaoxin and his watermelon candy Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies from his leader when he did his internship at Tencent. Each watermelon candy has it's sweetness which denoted by an inte

Super Mario(线段树离线区间k值)

以前见过这题,没做出来,知道是离线处理,这次仔细想了下, 首先把出现的高度都map离散化一下,以离散化出来的数目g建树,把每个位置都开俩个vector,一个存以这个位置为L的询问,一个存以这个位置为R的询问. 然后从1-g 进行更新,假如当前i是以第j个区间的开始位置,那么这时就可以询问一下<=p[j].h的个数s,显然这时第J个区间多加的,需要减掉,p[j].sum-=s; 然后更新第i个数,update(a[i],1,g,1);再找到某第k区间是以i结尾的,那么依旧询问一下,得出s,p[k]

gcd(线段树离线处理)——HDU 4630

对应HDU题目:点击打开链接 No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1801    Accepted Submission(s): 770 Problem Description Life is a game,and you lose it,so you suicide. But you can

数据结构(主席树):HDU 5654 xiaoxin and his watermelon candy

Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies from his leader when he did his internship at Tencent. Each watermelon candy has it's sweetness which denoted by an integer number. xiaoxin is very smart

SPOJ--K-query (线段树离线) 离线操作解决一下问题

K-query Given a sequence of n numbers a1, a2, ..., an and a number of k- queries. A k-query is a triple (i, j, k) (1 ≤ i ≤ j ≤ n). For each k-query (i, j, k), you have to return the number of elements greater than k in the subsequence ai, ai+1, ...,

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假

玲珑oj 1117 线段树+离线+离散化,laz大法

1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异世界,看到了一群可爱的妹子比如蕾姆啊,艾米莉亚啊,拉姆啊,白鲸啊,怠惰啊等等!有一天膜女告诉486说她的能力可能不能再用了,因为膜女在思考一个数据结构题,没心情管486了.486说我来帮你做,膜女说你很棒棒哦! 给一个集合,最开始为空(不是数学上的集合)五个操作: 1.插入x2.把小于x的数变成x3

HDU3874 线段树 + 离线处理

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 , 线段树(或树状数组) + 离线处理 下午做了第一道离线处理的题目(HDU4417),多少有点感觉,顺便就把这道题也给做了. 这道题就是要求某个区间内不重复数的和,自己在网上百度后参考别人的方法才AC的.参考来源:http://www.cnblogs.com/gj-Acit/p/3249827.html 这道题还是需要先离线处理数据,具体方法: ① 先用线段树把树给建立起来: ② 先把所有要