线段树+离线 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;
}
线段树+离线 hdu5654 xiaoxin and his watermelon candy的更多相关文章
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...
- 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon c ...
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组
xiaoxin and his watermelon candy Problem Description During his six grade summer vacation, xiaoxin g ...
- 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)
前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...
- 数据结构(主席树):HDU 5654 xiaoxin and his watermelon candy
Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies fro ...
- HDU 4638-Group(线段树+离线处理)
题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...
- HDU 4630-No Pain No Game(线段树+离线处理)
题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值 分析: 有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过, ...
- HDU 4288 Coder 【线段树+离线处理+离散化】
题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...
- 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 ...
随机推荐
- Extension Methods(扩展方法)
在 OOPL 中,有静态方法.实例方法和虚方法,如下: public sealed class String { public static bool IsNullOrEmpty(st ...
- P1257 平面上的最接近点对
题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 接下来n行:每行两个实数:x y, ...
- Ubuntu16安装jdk8配置Tomcat9
一.配置jdk 1.下载解压是肯定不能少的 2.配置环境变量根据自己需求来 export JAVA_HOME=/usr/software/jdk1.8.0_121 export CLASSPATH=. ...
- 【PL/SQL】用星号拼出金字塔
代码中首先声明了几个变量,然后使用嵌套循环去输出空格和星号,其中: 每层空格数=总层数-该层层数 每层星号数=当前层数*2-1 代码如下: declare v_number1 ); --外层循环控制金 ...
- Linux命令(文本编辑器)
vi和vim编辑器:有插入模式,一般模式,地行模式 一班模式通过(i.a.o.I.A.O)键--->进入插入模式 插入模式(按Esc键退出)---->j进入一班模式 ...
- 安装部署NetBeans mysql Tomact joget workflow 环境
一.安装joget workflow 1.安装jdk 下载jdk http://www.oracle.com/technetwork/java/javase/downloads/index.html ...
- c++ map: 使用struct或者数组做value
Notice 如果是program中有两个map对象,可能你需要两个map iterator,但是注意两个iter object不能命名一样,可以分别为iter1, iter2 Example #in ...
- DP背包问题小总结
DP的背包问题可谓是最基础的DP了,分为01背包,完全背包,多重背包 01背包 装与不装是一个问题 01背包基本模型,背包的总体积为v,总共有n件物体,每件物品的体积为v[i],价值为w[i],每件物 ...
- models中,对于(Small)IntegerField类型字段的choices参数在前端的展示
# models.py class UserInfo(models.Model): gender_choices = ( (1, "男"), (2, "女"), ...
- Python2 下Ubuntu linux Mac 安装 PyV8
在pip install PyV8(注意区分大小写)时,出现了如下报错 command 'x86_64-linux-gnu-gcc' failed with exit status 1 解决方案: 百 ...