「LGR-049」洛谷7月月赛 D.Beautiful Pair
[「LGR-049」洛谷7月月赛 D.Beautiful Pair](https://www.luogu.org/problemnew/show/P4755)
题目大意 : 给出长度为 \(n\) 的序列,求满足 \(i \leq j\) 且 $a_i \times a_j \leq \max(a_i..a_j) $ 的点对\((i, j)\)的数量
\(n \leq 10^5 \ 1 \leq a_i \leq 10^9\)
解题思路 :
直接枚举某一端点貌似很难维护极值,不妨对于每一个极值 \(a_k\),求 $ \max(a_i..a_j) \leq a_k$ 且 \(i \leq k \leq j\) 的点对数
考虑一个每一个点能作为\(\max\)统治的区间可以用单调栈求,并构建出笛卡尔树
此时对于每一个 \(a_k\) 答案由两部分产生:
- 点对 \((i, j)\) 满足 \(i = k\) 或 $j = k $,这一部分答案比较简单,就是统治区间内 \(1\) 的个数
- 点对 \((i, j)\) 满足 \(i \neq k\) 且 \(j \neq k\) ,此时答案等价于点 \(k\) 在笛卡尔树上的节点的左右子树中各取一个组成合法点对的方案数
第一种情况可以直接前缀和计算,在此不多做讨论,主要看第二种情况
由于是树上的子树问题,我们很容易想到用 \(dsu \ on\ tree\) 的做法来解决
不了解 \(dsu \ on \ tree\) 的可以戳这里的链接
枚举子树大小较小的子树,用树状数组维护较大的子树产生的贡献
对于较小子树中的点 \(u\) ,能与其组成合法点对的点 \(x\) 要满足 \(\frac{maxval}{a_u} \leq a_x\),直接用树状数组统计前缀和即可
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define N (500005)
#define int ll
int a[N], b[N], n, ans;
namespace Ls{
int s[N]; int lens = 0;
inline int calc(int x){
int res = upper_bound(s + 1, s + lens + 1, x) - s - 1;
return res;
}
inline void Realmain(){
for(int i = 1; i <= n; i++) s[i] = a[i];
sort(s + 1, s + n + 1);
lens = unique(s + 1, s + n + 1) - s - 1;
}
}
struct Fenwick{
int s[N];
inline int lowbit(int x){ return x & -x; }
inline void add(int x, int v){
for(int i = x; i <= n; i += lowbit(i)) s[i] += v;
}
inline int query(int x){
int ans = 0;
for(int i = x; i; i -= lowbit(i)) ans += s[i];
return ans;
}
}Bit;
namespace Treap{
int sz[N], ch[N][2], s[N], l[N], r[N], st[N], top;
inline void Getsize(int u){
sz[u] = 1;
int ls = ch[u][0], rs = ch[u][1];
if(ls) Getsize(ls), sz[u] += sz[ls];
if(rs) Getsize(rs), sz[u] += sz[rs];
if(!u) sz[u] = 0;
}
inline void Add(int u){
Bit.add(b[u], 1);
if(ch[u][0]) Add(ch[u][0]);
if(ch[u][1]) Add(ch[u][1]);
}
inline void Clear(int u){
Bit.add(b[u], -1);
if(ch[u][0]) Clear(ch[u][0]);
if(ch[u][1]) Clear(ch[u][1]);
}
inline int Count(int u, int val){
int pos = Ls::calc(val / a[u]);
int res = Bit.query(pos);
if(ch[u][0]) res += Count(ch[u][0], val);
if(ch[u][1]) res += Count(ch[u][1], val);
return res;
}
inline void solve(int u){
int p = sz[ch[u][0]] > sz[ch[u][1]] ? 0 : 1;
int ms = ch[u][p], ls = ch[u][p^1];
if(ls) solve(ls), Clear(ls);
if(ms) solve(ms);
if(ls) ans += Count(ls, a[u]);
if(u){ if(ls) Add(ls); Bit.add(b[u], 1); }
}
inline void Build(){
for(int i = 1; i <= n; i++){
while(a[st[top]] <= a[i] && top) r[st[top--]] = i - 1;
int f = st[top]; l[i] = f + 1;
ch[i][0] = ch[f][1], ch[f][1] = i, st[++top] = i;
}
for(int i = 1; i <= n; i++) if(!r[i]) r[i] = n;
}
inline void Realmain(){
Build(), Getsize(0), solve(0);
for(int i = 1; i <= n; i++) s[i] = s[i-1] + (a[i] == 1 ? 1 : 0);
for(int i = 1; i <= n; i++) ans += s[r[i]] - s[l[i]-1];
cout << ans << endl;
}
}
main(){
read(n);
for(int i = 1; i <= n; i++) read(a[i]);
Ls::Realmain();
for(int i = 1; i <= n; i++) b[i] = Ls::calc(a[i]);
Treap::Realmain();
return 0;
}
「LGR-049」洛谷7月月赛 D.Beautiful Pair的更多相关文章
- 「P4994」「洛谷11月月赛」 终于结束的起点(枚举
题目背景 终于结束的起点终于写下句点终于我们告别终于我们又回到原点…… 一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演.如果这次 NO ...
- 「P4996」「洛谷11月月赛」 咕咕咕(数论
题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...
- 「LuoguP4995」「洛谷11月月赛」 跳跳!(贪心
题目描述 你是一只小跳蛙,你特别擅长在各种地方跳来跳去. 这一天,你和朋友小 F 一起出去玩耍的时候,遇到了一堆高矮不同的石头,其中第 ii 块的石头高度为 h_ihi,地面的高度是 h_0 = 0 ...
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- 洛谷4月月赛R2
洛谷4月月赛R2 打酱油... A.koishi的数学题 线性筛约数和就可以\(O(N)\)了... #include <iostream> #include <cstdio> ...
- 洛谷3月月赛 R1 Step! ZERO to ONE
洛谷3月月赛 R1 Step! ZERO to ONE 普及组难度 290.25/310滚粗 t1 10分的日语翻译题....太难了不会... t2 真·普及组.略 注意长为1的情况 #include ...
- 【洛谷5月月赛】玩游戏(NTT,生成函数)
[洛谷5月月赛]玩游戏(NTT,生成函数) 题面 Luogu 题解 看一下要求的是什么东西 \((a_x+b_y)^i\)的期望.期望显然是所有答案和的平均数. 所以求出所有的答案就在乘一个逆元就好了 ...
- 【LGR-054】洛谷10月月赛II
[LGR-054]洛谷10月月赛II luogu 成功咕掉Codeforces Round #517的后果就是,我\(\mbox{T4}\)依旧没有写出来.\(\mbox{GG}\) . 浏览器 \( ...
- 【LGR-051】洛谷9月月赛
[LGR-051]洛谷9月月赛 luogu 签到题 description 给出\(K\)和质数\(m\),求最小的\(N\)使得\(111....1\)(\(N\)个\(1\))\(\equiv k ...
随机推荐
- 「6月雅礼集训 2017 Day7」三明治
[题目大意] $1 \leq n,m \leq 400$ N字形表示:上图第1行第1个那种:Z字形表示上图第1行第2个那种. [题解] 很容易得到结论: 考虑如果紫色比绿色先消去,那么黄色一定会比对应 ...
- 【游记】NOIP 2017
时间:2017.11.11~2017.11.12 地点:广东省广州市第六中学 Day1 T1:看到题目,心想这种题目也能放在T1? 这个结论我之前遇到过至少3次,自己也简单证明过.初见是NOIP200 ...
- 【STSRM10】dp只会看规律
[算法]区间DP [题意]平面上有n个点(xi,yi),用最少个数的底边在x轴上且面积为S的矩形覆盖这些点(在边界上也算覆盖),n<=100. [题解]随机大数据下,贪心几乎没有错误,贪心出奇迹 ...
- 【BZOJ】3779 重组病毒
[算法]Link-Cut Tree+线段树(维护DFS序) [题解]整整三天……T_T 这篇题解比较资瓷:permui 这道题虽然树形态没有变化,但用lct写的原因在于把题目中的操作一进行了神转化:每 ...
- BTA 常问的 Java基础40道常见面试题及详细答案(山东数漫江湖))
八种基本数据类型的大小,以及他们的封装类 引用数据类型 Switch能否用string做参数 equals与==的区别 自动装箱,常量池 Object有哪些公用方法 Java的四种引用,强弱软虚,用到 ...
- 解决不走onActivityResult方法
最近在开发公司项目,在使用startActivityForResult关联俩个Activity中,发现A跳转到B,B设置setResult之后,A没有执行onActivityResult,查找一下,发 ...
- 【转】gif文件格式详解
1.概述 ~~~~~~~~ GIF(Graphics Interchange Format,图形交换格式)文件是由 CompuServe公司开发的图形文件格式,版权所有,任何商业目的使用均须 Comp ...
- centos_7.1.1503_src_7
http://vault.centos.org/7.1.1503/os/Source/SPackages/ tex-fonts-hebrew-0.1-21.el7.src.rpm 05-Jul-201 ...
- sicily 1020. Big Integer
Description Long long ago, there was a super computer that could deal with VeryLongIntegers(no VeryL ...
- 系统调用wait()
进程一旦调用了 wait,就 立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息, 并把它彻底销毁后返回: ...