P4755-Beautiful Pair【笛卡尔树,线段树】
正题
题目链接:https://www.luogu.com.cn/problem/P4755
题目大意
\(n\)个数字的一个序列,求有多少个点对\(i,j\)满足\(a_i\times a_j\leq max\{a_k\}(k\in[l,r])\)
解题思路
如果构建一棵笛卡尔树的话那么两个点之间的\(max\)就在笛卡尔树的\(LCA\)位置。
所以对于每个位置维护一个线段树,然后每次暴力枚举小的那棵子树在大子树的线段树中查询即可。然后线段树合并或者启发式合并上去就好了。
建笛卡尔树的时候用\(\text{RMQ}\)查询区间最大值然后递归下去就好了。
当然因为是乘法所以小的那个值域不会超过\(\sqrt{10^9}\)所以也可以树状数组+启发式合并。
这里写的是线段树的做法,时间复杂度都是\(O(n\log^2 n)\)
注意\(1\)要特判就好了
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10,L=20;
int n,a[N],lg[N],f[N][L+1],inf;
long long ans;
struct Seg_Tree{
int cnt,w[N<<6],ls[N<<6],rs[N<<6];
void Change(int &x,int L,int R,int pos,int val){
if(!x)x=++cnt;w[x]+=val;
if(L==R)return;
int mid=(L+R)>>1;
if(pos<=mid)Change(ls[x],L,mid,pos,val);
else Change(rs[x],mid+1,R,pos,val);
return;
}
int Ask(int x,int L,int R,int l,int r){
if(!x||l>r)return 0;
if(L==l&&R==r)return w[x];
int mid=(L+R)>>1;
if(r<=mid)return Ask(ls[x],L,mid,l,r);
if(l>mid)return Ask(rs[x],mid+1,R,l,r);
return Ask(ls[x],L,mid,l,mid)+Ask(rs[x],mid+1,R,mid+1,r);
}
int Merge(int x,int y,int L,int R){
if(!x||!y)return x+y;
int mid=(L+R)>>1;w[x]+=w[y];
if(L==R)return x;
ls[x]=Merge(ls[x],ls[y],L,mid);
rs[x]=Merge(rs[x],rs[y],mid+1,R);
return x;
}
}T;
int Ask(int l,int r){
int z=lg[r-l+1];
int x=f[l][z],y=f[r-(1<<z)+1][z];
return (a[x]>=a[y])?x:y;
}
int solve(int l,int r){
if(l>r)return 0;
int x=Ask(l,r),ls,rs;
ls=solve(l,x-1);
rs=solve(x+1,r);
if(ls)ans+=T.Ask(ls,1,inf,1,1);
if(rs)ans+=T.Ask(rs,1,inf,1,1);
if(x-l<=r-x){
for(int i=l;i<x;i++)
ans+=T.Ask(rs,1,inf,1,a[x]/a[i]);
}
else{
for(int i=x+1;i<=r;i++)
ans+=T.Ask(ls,1,inf,1,a[x]/a[i]);
}
ls=T.Merge(ls,rs,1,inf);
T.Change(ls,1,inf,a[x],1);
return ls;
}
int main()
{
// printf("%d\n",sizeof(T)>>20);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
inf=max(inf,a[i]);
ans+=(a[i]==1);
f[i][0]=i;
}
inf=1e9;
for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++){
int x=f[i][j-1],y=f[i+(1<<j-1)][j-1];
if(a[x]>=a[y])f[i][j]=x;
else f[i][j]=y;
}
solve(1,n);
printf("%lld",ans);
return 0;
}
P4755-Beautiful Pair【笛卡尔树,线段树】的更多相关文章
- 【题解】P4755 Beautiful Pair(启发式合并的思路+分治=启发式分治)
[题解]P4755 Beautiful Pair upd: 之前一个first second烦了,现在AC了 由于之前是直接抄std写的,所以没有什么心得体会,今天自己写写发现 不知道为啥\(90\) ...
- 浅谈树套树(线段树套平衡树)&学习笔记
0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...
- YbtOJ#752-最优分组【笛卡尔树,线段树】
正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 \(n\)个人,每个人有\(c_i\)和\(d_i\)分别表示这个人所在的队伍的最少/最多人数. 然后 ...
- [HDOJ5877]Weak Pair(DFS,线段树,离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意:给一棵树和各点的权值a,求点对(u,v)个数,满足:1.u是v的祖先,2.a(u)*a(v ...
- poj 2155 matrix 二维线段树 线段树套线段树
题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- bzoj 3600 没有人的算术 - 替罪羊树 - 线段树
题目都是图片,就不给了,就给链接好了 由于bzoj比较慢,就先给[vjudge传送门] 有兴趣的可以去逛bzoj[bzoj传送门] 题目大意 有n个数a[1],a[2],...,a[n],它们开始都是 ...
- [NOI2019]弹跳(KD-Tree/四分树/线段树套平衡树 优化建图+Dijkstra)
本题可以用的方法很多,除去以下三种我所知道的就还有至少三种. 方法一:类似线段树优化建图,将一个平面等分成四份(若只有一行或一列则等分成两份),然后跑Dijkstra即可.建树是$O(n\log n) ...
- 【BZOJ-3306】树 线段树 + DFS序
3306: 树 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 792 Solved: 262[Submit][Status][Discuss] De ...
随机推荐
- 多线程同步AutoResetEvent 和ManualResetEvent
- jvm系列(六):jvm调优-工具篇
## jdk自带的工具### jconsole Jconsole(Java Monitoring and Management Console)是从java5开始,在JDK中自带的java监控和管理控 ...
- mysql ORDER BY 中文出现错误问题
在MySQL中,我们经常会对一个字段进行排序查询,但进行中文排序和查找的时候,对汉字的排序和查找结果往往都是错误的. 这种情况在MySQL的很多版本中都存在. 如果这个问题不解决,那么MySQL将无法 ...
- [题解] P4556 [Vani有约会]雨天的尾巴
[题解] P4556 [Vani有约会]雨天的尾巴 ·题目大意 给定一棵树,有m次修改操作,每次修改 \(( x\) \(y\) \(z )\) 表示 \((x,y)\) 之间的路径上数值 \(z\) ...
- netty系列之:自建客户端和HTTP服务器交互
目录 简介 使用客户端构建请求 accept-encoding server解析HTTP请求 总结 简介 上一篇文章,我们搭建了一个支持中文的HTTP服务器,并且能够从浏览器访问,并获取到相应的结果. ...
- 阿里云服务器上部署java项目(安装mysql)
安装mysql步骤如下: 1.安装MySQL官方的yum repository: wget -i -c http://dev.mysql.com/get/mysql57-community-relea ...
- Ubuntu16.04 Linux 下无痛安装、配置Gogs
本文在Win7+VMware的ubuntu 16.04中测试,安装Gogs,Install from binary. 准备工作: sudo apt-get install git sudo addus ...
- Jmeter的初体验--安装
准备工作 安装JMeter前需要安装配置好Java 一.安装 1.直接在官网下载安装即可,下载地址:http://jmeter.apache.org/download_jmeter.cgi,(Wind ...
- Windows下Rancher复制Pod内文件到本地
Rancher 未提供直接获取 Pod 内文件的工具(如果有请评论告知下,蟹蟹),但提供了 Rancher 的 CLI 客户端,通过 CLI 可以调用 k8s 的 CLI (kubectl) 命令来操 ...
- 并发编程之:BlockingQueue
大家好,我是小黑,一个在互联网苟且偷生的农民工. 队列 学过数据结构的同学应该都知道,队列是数据结构中一种特殊的线性表结构,和平时使用的List,Set这些数据结构相比有点特殊,它的特殊之处在于它只允 ...