传送门:点击打开链接

题意:一个三元组假设满足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;
}

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

  1. HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数

    xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...

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

    pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...

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

    xiaoxin and his watermelon candy Problem Description During his six grade summer vacation, xiaoxin g ...

  4. 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)

    前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...

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

    Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies fro ...

  6. HDU 4638-Group(线段树+离线处理)

    题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...

  7. HDU 4630-No Pain No Game(线段树+离线处理)

    题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值 分析: 有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过, ...

  8. HDU 4288 Coder 【线段树+离线处理+离散化】

    题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...

  9. 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 tri ...

随机推荐

  1. 更新换代之requests库

    好久不更新博客了... 之前的博文都是通过urllib2进行http访问,接下来我要说一个利器啊!requests模块,无法用语言对他进行赞扬了,需要的,有兴趣的,可以去了解下,移步官方中文文档: R ...

  2. kubernetes installing and using 单机版

    centos安装docker uname -r yum remove docker \ docker-client \ docker-client-latest \ docker-common \ d ...

  3. 如何下载 Nginx (windows 版本)并且简单的使用

    官网地址:http://nginx.org/ 进到官网 我这里下载的是 稳定版的 windows版本. 开始我们的简单测试 步骤一:找到nginx的压缩包,(随意找个地方)解压 步骤二:进入conf文 ...

  4. mysql自动增长的有关问题,怎么恢复从1开始

    mysql自动增长的问题,如何恢复从1开始在一个表中我设置到autoid为自动增长列例如有如下数据 1 张三 男 202 王五 男 223 李四 男 254 陈大 男 19 现在我把 autoid=3 ...

  5. windows 设置注册表服务自动启动

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\xxx\Start = ,=自动,,=禁用

  6. C# 获得Properties下的定义的资源

    var str1 = Properties.Resources.ResourceManager.GetObject("String1", null); string url = S ...

  7. [API 开发管理] 分享几个 eoLinker 实用操作技巧

    一键离线导出项目,PDF.WORD等格式任你挑选 举例说明,如果我要将 "示例素材项目" 导出到本地,并且以 PDF 的格式保存. 首先找到该项目所在空间:演示空间,在左边一级菜单 ...

  8. json 添加 和删除两种方法

    <script> var test = { name: "name", age: "12" }; var countrys = { "ne ...

  9. 第二节:Series基本属性及方法(下)

  10. 【Codeforces 126B】Password

    [链接] 我是链接,点我呀:) [题意] 给你一个字符串s 让你从中选出来一个字符串t 这个字符串t是s的前缀和后缀 且在除了前缀和后缀之外的中间部位出现过. 且要求t的长度最长. 让你输出这个字符串 ...