P4755 Beautiful Pair (分治 + 主席树)
题意:1e5的数组 计算有多少对 ai * aj <= max(ai ai+1...aj-1 aj)
题解:在处理这种涉及到区间极值的题时 好像是个套路分治 从级值中间分成两个区间
从区间短的那边暴力枚举算贡献 然后再分治下去
可以估计复杂度 一个点最多枚举n/2次 两个点最多枚举n/4次 4个点最多枚举n/8次...
枚举加起来的复杂度是nlogn
假设枚举了ai作为一个区间端点 问题就转化为统计极值另一边的区间找 <= zd / ai的个数
我是用主席树 然后写了个类似整体二分求的 看别人题解直接用的树状数组离线做显然复杂度更优秀
总共复杂度是nlognlogn
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5; ll ans;
int n, cnt, len;
int pre[MAXN];
int a[MAXN], b[MAXN], t[MAXN];
int zd[MAXN][25];
int ls[MAXN << 5], rs[MAXN << 5], sum[MAXN << 5]; int build(int l, int r) {
int rt = ++cnt;
int mid = l + r >> 1;
sum[rt] = 0;
if(l < r) {
ls[rt] = build(l, mid);
rs[rt] = build(mid + 1, r);
}
return rt;
} int add(int o, int l, int r, int k) {
int rt = ++cnt;
int mid = l + r >> 1;
ls[rt] = ls[o]; rs[rt] = rs[o]; sum[rt] = sum[o] + 1; if(l < r)
if(k <= mid) ls[rt] = add(ls[o], l, mid, k);
else rs[rt] = add(rs[o], mid + 1, r, k);
return rt;
} int query(int ql, int qr, int l, int r, int x) {
if(l == r) return b[l] <= x ? sum[qr] - sum[ql] : 0; int mid = l + r >> 1;
if(x <= b[mid]) return query(ls[ql], ls[qr], l, mid, x);
else return sum[ls[qr]] - sum[ls[ql]] + query(rs[ql], rs[qr], mid + 1, r, x);
} void solve(int l, int r) {
if(l >= r) return;
int lg = log2(r - l + 1);
int index;
if(a[zd[l][lg]] > a[zd[r - (1 << lg) + 1][lg]]) index = zd[l][lg];
else index = zd[r - (1 << lg) + 1][lg]; if(index - l < r - index) {
for(int i = l; i < index; i++) {
//if(a[i] == 1) ans++;
int now = a[index] / a[i];
ans += 1LL * query(t[index], t[r], 1, len, now);
}
} else {
for(int i = index + 1; i <= r; i++) {
//if(a[i] == 1) ans++;
int now = a[index] /a[i];
ans += 1LL * query(t[l - 1], t[index - 1], 1, len, now);
}
}
if(r - l + 1 >= 2) ans += 1LL * (pre[r] - pre[index] + pre[index - 1] - pre[l - 1]);
solve(l, index - 1);
solve(index + 1, r);
} int main() {
cnt = 0;
ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
for(int i = 1; i <= n; i++) zd[i][0] = i;
for(int i = 1; i <= n; i++) {
pre[i] = pre[i - 1];
if(a[i] == 1) pre[i]++;
} for(int j = 1; j <= 20; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++)
if(a[zd[i][j - 1]] > a[zd[i + (1 << j - 1)][j - 1]]) zd[i][j] = zd[i][j - 1];
else zd[i][j] = zd[i + (1 << j - 1)][j - 1]; sort(b + 1, b + 1 + n);
len = unique(b + 1, b + 1 + n) - b - 1;
t[0] = build(1, len);
for(int i = 1; i <= n; i++) {
int tt = lower_bound(b + 1, b + 1 + len, a[i]) - b;
t[i] = add(t[i - 1], 1, len, tt);
} solve(1, n);
for(int i = 1; i <= n; i++)
if(a[i] == 1) ans++;
printf("%lld\n", ans);
return 0;
}
P4755 Beautiful Pair (分治 + 主席树)的更多相关文章
- 洛谷 P4755 - Beautiful Pair(主席树+分治+启发式优化)
题面传送门 wssb,我紫菜 看到这类与最大值统计有关的问题可以很自然地想到分治,考虑对 \([l,r]\) 进行分治,求出对于所有 \(l\le x\le y\le r\) 的点对 \((x,y)\ ...
- 【题解】P4755 Beautiful Pair(启发式合并的思路+分治=启发式分治)
[题解]P4755 Beautiful Pair upd: 之前一个first second烦了,现在AC了 由于之前是直接抄std写的,所以没有什么心得体会,今天自己写写发现 不知道为啥\(90\) ...
- 洛谷$P4755\ Beautiful\ Pair$ 最大值分治
正解:最大值分治 解题报告: 传送门$QwQ$ 昂考虑如果已经钦定了点$x$是这个$max$了,然后现在要求有多少对$[l,r]$满足$a_x=max\left\{a_i\right\},i\in[l ...
- LOJ#3097 [SNOI2019]通信 最小费用最大流+cdq分治/主席树/分块优化建图
瞎扯 我们网络流模拟赛(其实是数据结构模拟赛)的T2. 考场上写主席树写自闭了,直接交了\(80pts\)的暴力,考完出来突然发现: woc这个题一个cdq几行就搞定了! 题意简述 有\(n\)个哨站 ...
- BZOJ 1935 Tree 园丁的烦恼 CDQ分治/主席树
CDQ分治版本 我们把询问拆成四个前缀和,也就是二维前缀和的表达式, 我们把所有操作放入一个序列中 操作1代表在x,y出现一个树 操作2代表加上在x,y内部树的个数 操作3代表减去在x,y内部树的个数 ...
- [IOI2014]holiday假期(分治+主席树)
题目描述 健佳正在制定下个假期去台湾的游玩计划.在这个假期,健佳将会在城市之间奔波,并且参观这些城市的景点.在台湾共有n个城市,它们全部位于一条高速公路上.这些城市连续地编号为0到n-1.对于城市i( ...
- luogu P4755 Beautiful Pair
luogu 这题有坨区间最大值,考虑最值分治.分治时每次取出最大值,然后考虑统计跨过这个位置的区间答案,然后两边递归处理.如果之枚举左端点,因为最大值确定,右端点权值要满足\(a_r\le \frac ...
- [BZOJ4367][IOI2014]Holiday(决策单调性+分治+主席树)
4367: [IOI2014]holiday假期 Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 421 Solved: 128[Submit][Sta ...
- P4755 Beautiful Pair
题目 洛谷 做法 \(i≤x≤j,a[i]<\frac{a[x]}{a[j]}\) 考虑\(a[x]\)的贡献,单调栈预处理\(L,R\)能作为最大值的区间 枚举一端点,仅需另一端点满足条件即可 ...
随机推荐
- 集成spring框架的web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" ...
- 【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)
关键字说明 什么是 Azure Active Directory?Azure Active Directory(Azure AD, AAD) 是 Microsoft 的基于云的标识和访问管理服务,可帮 ...
- MySQL的CURD 增删改查
添加 insert 语法: 单条:insert into 表名('字段1', '字段2', ...) values('值1', '值2', ...) 多条:insert into 表名('字段1', ...
- 【排序基础】5、插入排序法 - Insertion Sort
插入排序法 - Insertion Sort 文章目录 插入排序法 - Insertion Sort 插入排序设计思想 插入排序代码实现 操作:插入排序与选择排序的比较 简单记录-bobo老师的玩转算 ...
- 【Oracle】修改oracle中SGA区的大小
1.备份数据库: 2.关机,拔下电源和各种连接线,抽出机箱,打开机箱上盖,增加内存: 3.完成后按原样将各个部件及连接线恢复好,电开机,系统正常运行: 4.进入系统查看,发现内存已经顺利安装: 5.修 ...
- Oracle备份审计表SYS.AUD$和SYS.FGA_LOG$
ORACLE的审计表不可以使用expdp和impdp导出和导入,如果使用,会报如下错误: 需要使用exp和imp进行导出和导出 导出语句: exp " '/ as sysdba' " ...
- 2021年官网下载各个版本JDK最全版与官网查阅方法
版本说明 1.安装部署JDK (1)环境 (2)官网下载JDK 由于官网的地址会随着时间的修改而更改修改下载地址,现在讲述下通用的界面操作下载JDK,以后JDK收费更严重,估计就只能下载开源的了. A ...
- 如何创建一个验证请求的API框架
开发一款成功软件的关键是良好的架构设计.优秀的设计不仅允许开发人员轻松地编写新功能,而且还能丝滑的适应各种变化. 好的设计应该关注应用程序的核心,即领域. 不幸的是,这很容易将领域与不属于这一层的职 ...
- 从零搭建一个IdentityServer——集成Asp.net core Identity
前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一个基础的验证服务器,并实现了基于客户端证书的Oauth2.0授权流程,以及通过access token访问被保护 ...
- zabbix客户端监控脚本shell
zabbix客户端监控脚本shell #!/bin/sh sleep 3 zabbixdir=`pwd` zabbix_version=4.2.5 ###指定版本,最好和server端吻合版本,可以自 ...