传送门:点击打开链接

题意:一个三元组假设满足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. [转]mysql触发器的作用及语法

    转自:http://blog.csdn.net/cloudday/article/details/6905590 触发器是一种特殊的存储过程,它在插入,删除或修改特定表中的数据时触发执行,它比数据库本 ...

  2. ubuntu上Hadoop三种运行模式的部署

    Hadoop集群支持三种运行模式:单机模式.伪分布式模式,全分布式模式,下面介绍下在Ubuntu下的部署 (1)单机模式 默认情况下,Hadoop被配置成一个以非分布式模式运行的独立JAVA进程,适合 ...

  3. SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础

    SAS学习笔记之<SAS编程与数据挖掘商业案例>(1)系统简介和编程基础 1. SAS系统简介 1.1 SAS是先编译后执行的语言,data步标志着编译的开始. 数据指针:当前内存缓存区, ...

  4. 集合Set、List、Map的遍历方法

    package com.shellway.javase; import java.util.ArrayList; import java.util.Collection; import java.ut ...

  5. 用sed替换含反斜(\)的字符串

    今天在linux替换配置文件时,test文件里有一个字符串 e:\ 需要换成/usr/home/ 用了sed命令:sed -i "s?e:\\?/usr/home/?g" test ...

  6. C# 扩展类的内置方法

    public class A//先定义A类 { } public static class Extension//必须先声明一个静态类,类名随意 { public static int ToInt32 ...

  7. CAD调用移动命令

    主要用到函数说明: _DMxDrawX::SendStringToExecuteFun 把命令当着函数执行,可以传参数,详细说明如下: 参数 说明 IDispatch* pParam 命令参数,IMx ...

  8. Asp.Mvc 常用

    url转义 var address = "http://www.cnblog.com"; var a22 = Uri.EscapeDataString(address); var ...

  9. 【原创】使用HTML5+canvas+JavaScript开发的原生中国象棋游戏及源码分享

    目前已经实现的功能: V1.0 : 实现棋子的布局,画布及游戏场景的初始化V2.0 : 实现棋子的颜色改变V3.0 :实现所有象棋的走棋规则V4.0 : 实现所有棋子的吃子功能 GItHub源码下载地 ...

  10. vue 实现点赞

    在v-for循环里 <ul class="project_content"> <li v-for="(item, index) in items&quo ...