https://www.luogu.org/problemnew/show/P4755

考虑分治,在 [l, r] 区间中用线段树找到最大的一个点,处理经过它的可行数对的个数,统计个数可以离线树状数组处理

因为最多被分成 2n 个区间(像线段树一样),对于每个区间使用类似于启发式合并的思想将要处理的区间放到 vector 里面,最多有 n log n 个查询,复杂度 n log^2 n

#include <bits/stdc++.h>
#define For(i, a, b) for(int i = a; i <= b; i++)
using namespace std; typedef unsigned long long ull;
typedef long long ll; template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}
while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
} const int N = 1e5 + 5; int Max[N << 2], wz[N << 2], a[N], pre[N], f[N];
long long ans;
int n, len; void build(int u, int l, int r) {
if(l == r) {
Max[u] = a[l];
wz[u] = l;
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
if(Max[u << 1] > Max[u << 1 | 1]) Max[u] = Max[u << 1], wz[u] = wz[u << 1];
else Max[u] = Max[u << 1 | 1], wz[u] = wz[u << 1 | 1];
} int Q1, Q2; void query(int u, int l, int r, int L, int R) {
if(l <= L && R <= r) {
if(Max[u] > Q1) {
Q1 = Max[u];
Q2 = wz[u];
}
return;
}
int mid = (L + R) >> 1;
if(mid >= l) query(u << 1, l, r, L, mid);
if(mid + 1 <= r) query(u << 1 | 1, l, r, mid + 1, R);
} int lowbit(int x) {return x & -x;}
void add(int x) {for(int i = x; i <= n; i += lowbit(i)) f[i]++;}
int query(int x) {int ans = 0; for(int i = x; i; i -= lowbit(i)) ans += f[i]; return ans;} struct ele {
int l, r, v;
bool operator < (const ele A) const {return v < A.v;}
ele (int a, int b, int c) : l(a), r(b), v(c) {}
ele () {}
}; vector <ele> Q;
vector <int> t[N]; void solve(int l, int r) {
if(l > r) return;
Q1 = 0; query(1, l, r, 1, n);
int L = Q2 - l, R = r - Q2; int tmp = Q2;
if(L < R) for(int i = l; i <= Q2; i++) { Q.push_back(ele(Q2, r, pre[Q1] / pre[a[i]])); }
else for(int i = Q2; i <= r; i++) Q.push_back(ele(l, Q2, pre[Q1] / pre[a[i]]));
solve(l, tmp - 1); solve(tmp + 1, r);
} int main() {
cin >> n;
for(int i = 1; i <= n; i++) { read(a[i]), pre[i] = a[i]; };
sort(pre + 1, pre + n + 1); len = unique(pre + 1, pre + n + 1) - pre - 1;
for(int i = 1; i <= n; i++) a[i] = lower_bound(pre + 1, pre + len + 1, a[i]) - pre;
build(1, 1, n); solve(1, n);
for(vector <ele> :: iterator it = Q.begin(); it != Q.end(); it++) it -> v = upper_bound(pre + 1, pre + len + 1, it -> v) - pre - 1;
for(int i = 1; i <= n; i++) t[a[i]].push_back(i);
sort(Q.begin(), Q.end()); int LEN = Q.size(), now = 0;
for(int i = 0; i <= len; i++) {
for(vector <int> :: iterator it = t[i].begin(); it != t[i].end(); it++) add(*it);
while(Q[now].v == i && now < LEN) {
ans += (long long)(query(Q[now].r) - query(Q[now].l - 1));
now++;
}
}
cout << ans << endl;
return 0;
}

luoguP4755 Beautiful Pair的更多相关文章

  1. 「LGR-049」洛谷7月月赛 D.Beautiful Pair

    「LGR-049」洛谷7月月赛 D.Beautiful Pair 题目大意 : 给出长度为 \(n\) 的序列,求满足 \(i \leq j\) 且 $a_i \times a_j \leq \max ...

  2. [luogu4755]Beautiful Pair

    [luogu4755]Beautiful Pair luogu 第一次写最大值分治感觉有点丑 每次找到最大值mid,扫小的一边,主席树查大的一边小于等于\(\frac{a[mid]}{a[i]}\)的 ...

  3. 【题解】P4755 Beautiful Pair(启发式合并的思路+分治=启发式分治)

    [题解]P4755 Beautiful Pair upd: 之前一个first second烦了,现在AC了 由于之前是直接抄std写的,所以没有什么心得体会,今天自己写写发现 不知道为啥\(90\) ...

  4. Luogu4755 Beautiful Pair 最值分治、主席树

    传送门 整天做一些模板题感觉药丸 设\(val_i\)表示第\(i\)个位置的值 看到区间最大值考虑最值分治.对于当前的区间\([l,r]\),找到区间最大值\(mid\),递归\([l,mid-1] ...

  5. 洛谷 P4755 - Beautiful Pair(主席树+分治+启发式优化)

    题面传送门 wssb,我紫菜 看到这类与最大值统计有关的问题可以很自然地想到分治,考虑对 \([l,r]\) 进行分治,求出对于所有 \(l\le x\le y\le r\) 的点对 \((x,y)\ ...

  6. Luogu 4755 Beautiful Pair

    分治 + 主席树. 设$solve(l, r)$表示当前处理到$[l, r]$区间的情况,我们可以找到$[l, r]$中最大的一个数的位置$mid$,然后扫一半区间计算一下这个区间的答案. 注意,这时 ...

  7. P4755 Beautiful Pair

    题目 洛谷 做法 \(i≤x≤j,a[i]<\frac{a[x]}{a[j]}\) 考虑\(a[x]\)的贡献,单调栈预处理\(L,R\)能作为最大值的区间 枚举一端点,仅需另一端点满足条件即可 ...

  8. luogu P4755 Beautiful Pair

    luogu 这题有坨区间最大值,考虑最值分治.分治时每次取出最大值,然后考虑统计跨过这个位置的区间答案,然后两边递归处理.如果之枚举左端点,因为最大值确定,右端点权值要满足\(a_r\le \frac ...

  9. 洛谷$P4755\ Beautiful\ Pair$ 最大值分治

    正解:最大值分治 解题报告: 传送门$QwQ$ 昂考虑如果已经钦定了点$x$是这个$max$了,然后现在要求有多少对$[l,r]$满足$a_x=max\left\{a_i\right\},i\in[l ...

随机推荐

  1. 75. Sort Colors (Array)

    Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...

  2. Maven01 环境准备、maven项目结构、编译/测试/打包/清除、安装、

    0 前提准备 0.1 安装java开发环境 0.2 安装maven工具 1 maven项目基本结构 如图所示,整个maven项目有业务文件.测试文件.POM依赖管理文件:其实还有一个资源文件resou ...

  3. &&与||的短路运算

    在谈&&和||两个运算符的短路运算之前,先看一段程序: #include <stdio.h> int main() { , para2 = , para3 = , para ...

  4. 对比Nginx配置文件差异

    一.概要: Python2 官方文档:https://docs.python.org/2/library/difflib.html Python2 官方文档:https://docs.python.o ...

  5. SpringBoot中使用AOP实现计算Service执行时间

    1.增加POM.XML的依赖架包 <!-- 引入 spring aop 依赖 --><dependency> <groupId>org.springframewor ...

  6. Appium Windows安装

    安装环境 1 安装Nodejs 下载nodejs安装包(http://nodejs.org/download/)安装 测试安装是否成功:运行cmd,输入node -v 2 安装android的SDK ...

  7. CTE递归限制次数

    CTE可以用来取递归,网上资料很多,这里就不再叙述了,今天遇到的需求是要限制只取2级,然后加了个临时的lev with tree as(select [CustomerID],[CustomerNam ...

  8. eclipse 按装lombok与注解说明

    原文:http://www.cnblogs.com/ywqbj/p/5711691.html 一.安装lombok 1.下载   lombok-1.16.16.jar 包 我的下载完后放到:/root ...

  9. 【转载】实战mysql分区(PARTITION)

    转载地址:http://lobert.iteye.com/blog/1955841 前些天拿到一个表,将近有4000w数据,没有任何索引,主键.(建这表的绝对是个人才) 这是一个日志表,记录了游戏中物 ...

  10. java中super的用法

    在Java中,super关键字有2个用法,一个是访问父类的函数,一个是访问父类的变量,总体来说,就是一个功能,访问父类的成员. 代码如下: class Person { String name ; i ...