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. Linux运维基础入门(三):网络基础知识梳理03

    一,ARP协议 使用ARP协议可以查出擅自更改IP地址主机的MAC地址.在学习ARP协议前需要了解广播和广播域的相关概念. 1.1 广播与广播域 在超市找人时,如果不知道对方的位置就需要到服务台通过广 ...

  2. hdu3999-The order of a Tree (二叉树的先序遍历)

    http://acm.hdu.edu.cn/showproblem.php?pid=3999 The order of a Tree Time Limit: 2000/1000 MS (Java/Ot ...

  3. Quaternion.identity是什么意思?

    Quaternion.identity就是指Quaternion(0,0,0,0),

  4. Unity游戏语音(富文本消息)解决方案GVoice

    腾迅云-GVoice https://www.qcloud.com/document/product/556/7673 集成1-2天内可搞定,博主亲测 Unity5.4.4f1 今天又试了下语音转文字 ...

  5. Hibernate其它API

    ----------------siwuxie095 (一)Query 1.使用 Query 对象执行查询操作,不需要写 sql 语句,但是要写 hql 语句 (1)hql:即 Hibernate Q ...

  6. java.util.regex.PatternSyntaxException, dangling metacharacter “?” 解决方法

    今天在用正则表达式的时候遇到这样一个异常 看了相关资料后发现这是因为在正则表达式中,像"?","*","\"都是保留字符,所以在用的时候需要 ...

  7. 不同Hadoop模式下,Hive元数据文件存储位置

    假如在hive的配置文件hive-site.xml中,属性hive.metastore.warehouse.dir被设置为/root/hive/warehouse. 如果Hadoop是本地模式,则仓库 ...

  8. OpenSceneGraph3.4.0+Qt5.6.1MinGW开发环境部署

                基本步骤如下描述: Step1:CMake3.10编译openscenegraph3.4.0,生成makefile文件(中间过程可能会涉及到很多三方库,需要下载编译,然后按cm ...

  9. 浅谈 js中parseInt函数的解析[转]

    首先还是从很热门的实例parseInt("09")==0说起. parseInt(number,type)这个函数后面如果不跟第2个参数来表示进制的话,默认是10进制. 比如说pa ...

  10. Ubuntu14.04下FTP服务器的搭建配置 标签: ubuntuftp服务器虚拟机 2017-06-13 15:24 161人阅读 评

    首先说明一下,我是在虚拟机中装的Ubuntu14.04,物理机是Win10,最初只是为了在两个系统间传输文件才在Ubuntu中安装了ftp服务器,从Windows端登陆其即可.最初也是按照网上的各种教 ...