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\)能作为最大值的区间 枚举一端点,仅需另一端点满足条件即可 ...
随机推荐
- openstack octavia的实现与分析(一)openstack负载均衡的现状与发展以及lvs,Nginx,Haproxy三种负载均衡机制的基本架构和对比
[负载均衡] 大量用户发起请求的情况下,服务器负载过高,导致部分请求无法被响应或者及时响应. 负载均衡根据一定的算法将请求分发到不同的后端,保证所有的请求都可以被正常的下发并返回. [主流实现-LVS ...
- 【Linux】nginx详细说明
Nginx的配置文件nginx.conf配置详解如下: user nginx nginx ; Nginx用户及组:用户 组.window下不指定 worker_processes 8; 工作进程:数目 ...
- SQL Server management studio使用sa连接时报错与伺服器的连接已成功,但在登入程序是发生错误
使用Sql Server management studio的sa用户连接数据库时,报如下错误 解决方法: 1.使用windows验证登录 2.右键点击连接,点击属性,点击安全性,选择混合验证 3.重 ...
- win10打开IIS服务并发布网站
1.打开控制面板 win+x后点击控制面板 2.点击程序集下边的解除安装程式 3.点击开启或关闭windows功能 4.找到Internet information services并勾选前面的复选框 ...
- 对于Update Function Modules的一点说明
To be able to call a function module in an update work process, you must flag it in the Function Bui ...
- VBA调用数独求解器
我开发了一个用于求解数独的dll文件,只需要双击一下注册表文件,就可以在VBA中调用这个功能了.具体步骤如下: 下载:https://share.weiyun.com/5dpcNqx 找到ExcelS ...
- 使用 gitlab-runner 持续集成
gitlab-runner 是 Gitlab 推出的与 Gitlab CI 配合使用的持续集成工具.当开发人员在 Gitlab 上更新代码之后,Gitlab CI 服务能够检测到代码更新,此时可以触发 ...
- (17)-Python3之--文件操作
1.文件的操作流程 第一,建立文件对象. 第二,调用文件方法进行操作. 第三,不要忘了关闭文件.(文件不关闭的情况下,内容会放在缓存,虽然Python会在最后自动把内容读到磁盘,但为了以防万一,要养成 ...
- JAVA不可不知的强软弱虚四种引用
一个变量指向new对象,就是引用,在java中有四种引用,分别是强软弱虚,常见的Object o = new Object(),就是强引用,垃圾回收的时候,强引用不会被回收. 公用类: publi ...
- Centos虚拟机上安装部署Tenginx,以及部署过程中遇到的问题
Tenginx下载网址: Tenginx 官网地址:http://tengine.taobao.org/ Tenginx的官方网址中可以阅读Nginx的文档,可以选择中文进行阅读.下载Tengine- ...