正题

题目链接:https://www.luogu.com.cn/problem/P4755


题目大意

nnn个数字的一个序列,求有多少个点对i,ji,ji,j满足ai×aj≤max{ak}(k∈[l,r])a_i\times a_j\leq max\{a_k\}(k\in[l,r])ai​×aj​≤max{ak​}(k∈[l,r])


解题思路

如果构建一棵笛卡尔树的话那么两个点之间的maxmaxmax就在笛卡尔树的LCALCALCA位置。

所以对于每个位置维护一个线段树,然后每次暴力枚举小的那棵子树在大子树的线段树中查询即可。然后线段树合并或者启发式合并上去就好了。

建笛卡尔树的时候用RMQ\text{RMQ}RMQ查询区间最大值然后递归下去就好了。

当然因为是乘法所以小的那个值域不会超过109\sqrt{10^9}109​所以也可以树状数组+启发式合并。

这里写的是线段树的做法,时间复杂度都是O(nlog⁡2n)O(n\log^2 n)O(nlog2n)

注意111要特判就好了


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【笛卡尔树,线段树】相关推荐

  1. 洛谷 - P4755 Beautiful Pair(笛卡尔树+主席树)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,现在一个数对 ( i , j ) 如果满足 a[ i ] * a[ j ] <=max( a[ i ] ~ a[ j ] ),则称其 ...

  2. 树套树-线段树套平衡树

    作用 线段树的作用是区间修改和查询,平衡树的作用是查询第k大,k的排名,前驱,后继.这两个结合起来,就变成了可以区间修改和查询第k大,k的排名,前驱,后继的数据结构:树套树-线段树套平衡树. 实现 先 ...

  3. 牛客 - sequence(笛卡尔树+线段树)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a 和数列 b ,求 题目分析:不算难的题目,对于每个 a[ i ] 求一下贡献然后维护最大值就好,具体思路就是,先找出每个 a[ i ] 左 ...

  4. YbtOJ#752-最优分组【笛卡尔树,线段树】

    正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 nnn个人,每个人有cic_ici​和did_idi​分别表示这个人所在的队伍的最少/最多人数. 然后 ...

  5. P5044-[IOI2018] meetings 会议【dp,笛卡尔树,线段树二分】

    正题 题目链接:https://www.luogu.com.cn/problem/P5044 题目大意 给出一个长度为nnn的序列hhh,定义dis(x,y)=max{hi}(x≤i≤y)dis(x, ...

  6. P4755 Beautiful Pair (数据结构+分治)

    题意: 小D有个数列a ,当一个数对(i,j)(i≤j)(i,j)(i\leq j)(i,j)(i≤j)满足 aia_iai​和 aj​a_j​aj​​ 的积不大于 ai,ai+1​,........ ...

  7. 线段树 ---- 线段树维护线段相加+滑动变长窗口 2021牛客多校第7场 F xay loves trees

    题目大意: 给你两个大小相同的树但是形状不一定一样 叫你选出最大的子集,满足下面两个条件 在第一颗树上是一条链 在第二颗树上任意两个点都不是祖先关系 解题思路: 首先我们现在第二颗树上面把每个点的df ...

  8. 2021CCPC(桂林) - Suffix Automaton(后缀树+线段树)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,再给出 qqq 次询问,每次询问需要输出本质不同第 kkk 小的子串的起止位置.如果有多个答案,输出起点最小的那个. 本题规定字符串大小 ...

  9. BZOJ 3685: 普通van Emde Boas树( 线段树 )

    建颗权值线段树就行了...连离散化都不用... 没加读入优化就TLE, 加了就A掉了...而且还快了接近1/4.... ---------------------------------------- ...

最新文章

  1. 怎么学python-如何轻松学习Python数据分析
  2. 在VM虚拟机Windows Server r2上部署安装Microsoft Dynamics CRM 2016 步骤详解(一)
  3. XML数据的分页显示
  4. Android的多任务之路
  5. 相机标定(二)深入理解四大坐标系与其变换关系
  6. 【渝粤教育】电大中专新媒体营销实务 (3)作业 题库
  7. 拜年+红包,都有份儿!
  8. 你还在为文件读写而烦恼?Python已经轻松帮你解决了(建议学习)
  9. 服务发现和注册和Eureka
  10. pandas练习题二
  11. mongo-connector导入数据到Es
  12. mongodb 系列 ~ mongo的两种引擎对比
  13. C++ 房贷计算 : 等额本金和等额本息
  14. 最小割集stoer_wagner算法
  15. 社区专家谈 12306
  16. xcopy 跳过已经存在的_虚拟网红卖真衣服,真实人类已经开始买“假”衣服了!...
  17. iOS高德地图去logo
  18. 新氧,今天受了点儿伤
  19. 怎样在CSDN博客挂广告
  20. 如何检测文章被搜索引擎收录(如何让搜索引擎收录网站)

热门文章

  1. java关于异常的面试程序题_Java挑战:最难的十个面试题(附答案)「下」
  2. java bouncycastle_java – 使用bouncycastle进行签名和验证签名的正确方法
  3. 连接mysql数据库2013_使用VS2013 + EF6 + .NET4.5 连接Mysql数据库
  4. python中merge函数怎么用_Python Merge函数原理及用法解析
  5. java class类型参数_使用Class对象实例化Java类型参数/ generic
  6. ai的预览模式切换_AI字体制作,用AI制作创意阶梯式文字
  7. leetcode300. 最长递增子序列
  8. 浅谈前端路由原理hash和history
  9. qt 实现html 编辑器,基于QT的HTML编辑器的设计与实现.doc
  10. 计算机网络 哪个教材好,学习计算机网络哪本教材最好?