牛客网多校训练第四场C sequence
(牛客场场有笛卡尔树,场场都不会用笛卡尔树。。。自闭,补题心得)
题目链接:https://ac.nowcoder.com/acm/contest/884/C
题意:给出两个序列a,b,求max{min a[l,r]*sum b[l,r]}
一个比较显然的做法是通过线段树/ST表维护区间最值,不过nlogn的做法容易被卡常,(zkw线段树可过)不过赛时提高了时限到3s,基本上就很好写了
直接维护区间最小/大值下标,然后从最小值开始进行计算答案,在最小值的左边找到最小/最大的前缀和(找最大是为了处理min a[i]<0的情况),最小值的右边也找到最小/最大值的前缀和,计算一次答案,然后以最小值为分界,划分为两部分继续计算即可
线段树查询效率logn,总复杂度O(nlogn),ST表预处理nlogn,总复杂度也是O(nlogn)且常数较大,赛后发现有神仙用了O(n)的做法,也学习了一下,没错,就是神奇的笛卡尔树
我们分析这个求解答案的过程,发现就是先找最小值,然后找次小...的顺序,我们对a数组构建笛卡尔树,那么这个求解答案的过程就是对树的dfs的过程,既然是对树的dfs,我们就可以用mn[rt],mx[rt]数组来记录以rt为根这颗子树中包含前缀和的最小前缀和,
然后在dfs的过程中,用子树不断更新即可,然后我们O(1)地计算每颗子树的答案即可,总体复杂度是O(n)的
笛卡尔树:
通过单调栈来构造,这个过程是O(n)的,每次元素x入栈,找到前一个比他小的元素p,那么它就是这颗笛卡尔树上元素p对应节点的右儿子,原先的右儿子q变成了当前插入元素x的左儿子,原先的右儿子q也就是最后一个出栈的元素,如果没有元素出栈,那就是作为一个叶子节点插入了笛卡尔树,插入位置是未入栈时栈顶元素的右儿子
笛卡尔树的性质:元素下标满足二叉搜索树的性质,元素值满足堆的性质
笛卡尔树根节点是单调栈栈底元素,也是整个序列的最小值,每颗子树的根节点都是一个范围内的极小值,树上两个元素的LCA可以用来解决RMQ问题
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 3e6+;
int a[N];
ll b[N];
int son[N][],n;//0左儿子1右儿子
int sta[N];
ll mn[N],mx[N];//记录当前子树中最小、最大的前缀和
ll ans=-3e18;
void dfs(int rt,int l,int r)
{
if(son[rt][])dfs(son[rt][],l,rt-);
if(son[rt][])dfs(son[rt][],rt+,r);
//左子树不包括l-1这个点,然而我们要将这个前缀和考虑进去,否则会少计算到b[l],右子树不包括根节点,b[rt]也要考虑进去
ll minl=min(mn[son[rt][]],b[l-]);
ll maxl=max(mx[son[rt][]],b[l-]);
ll minr=min(mn[son[rt][]],b[rt]);
ll maxr=max(mx[son[rt][]],b[rt]);
ans=max(ans,a[rt]*(maxr-minl));
ans=max(ans,a[rt]*(minr-maxl));
//这样写同时也把当前子树根考虑进去了
mn[rt]=min(minl,minr);
mx[rt]=max(maxl,maxr);
}
int main()
{
int n;
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
cin>>n;
int top=;
for(int i=;i<=n;i++)
{
cin>>a[i];
while (top&&a[i]<a[sta[top]])son[i][]=sta[top--];
if(top)son[sta[top]][]=i;
sta[++top]=i;
}
for(int i=;i<=n;i++)
{
cin>>b[i];
b[i]+=b[i-];
}
mn[]=3e18;mx[]=-3e18;
dfs(sta[],,n);
cout<<ans<<endl;
return ;
}
牛客网多校训练第四场C sequence的更多相关文章
- 牛客网多校训练第三场 A - PACM Team(01背包变形 + 记录方案)
链接: https://www.nowcoder.com/acm/contest/141/A 题意: 有n(1≤n≤36)个物品,每个物品有四种代价pi,ai,ci,mi,价值为gi(0≤pi,ai, ...
- 牛客网多校训练第三场 C - Shuffle Cards(Splay / rope)
链接: https://www.nowcoder.com/acm/contest/141/C 题意: 给出一个n个元素的序列(1,2,...,n)和m个操作(1≤n,m≤1e5),每个操作给出两个数p ...
- 牛客网多校训练第八场A All one Matrix
题目链接:https://ac.nowcoder.com/acm/contest/888/A 题意:求出有多少个不被包含的全1子矩阵 解题思路:首先对列做处理,维护每个位置向上1的个数,然后我们从最后 ...
- 牛客网多校训练第二场D Kth Minimum Clique
链接:https://ac.nowcoder.com/acm/contest/882/D来源:牛客网 Given a vertex-weighted graph with N vertices, fi ...
- 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】
链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...
- 牛客网多校赛第七场J--Sudoku Subrectangle
链接:https://www.nowcoder.com/acm/contest/145/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...
- 牛客网多校赛第七场--C Bit Compression【位运算】【暴力】
链接:https://www.nowcoder.com/acm/contest/145/C 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524 ...
- 牛客网多校赛第七场A--Minimum Cost Perfect Matching【位运算】【规律】
链接:https://www.nowcoder.com/acm/contest/145/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...
- 牛客网多校训练第一场 J - Different Integers(树状数组 + 问题转换)
链接: https://www.nowcoder.com/acm/contest/139/J 题意: 给出n个整数的序列a(1≤ai≤n)和q个询问(1≤n,q≤1e5),每个询问包含两个整数L和R( ...
随机推荐
- jquery hover中嵌套mouseenter,mouseenter函数执行多次的问题解决方案
已知晓在jq中hover的API就是把mouseenter和mouseleave组合在一起来用的,在jq中实现`hover:function(fnOver,fnOut){return this.mou ...
- Python面试题之“猴子补丁”(monkey patching)指的是什么?这种做法好吗?
“猴子补丁”就是指,在函数或对象已经定义之后,再去改变它们的行为. 举个例子: import datetime datetime.datetime.now = lambda: datetime.dat ...
- iview 的table组件,自带过滤功能
html : <Table :columns="people" :data="scores"></Table> data: people ...
- Java菜鸟笔记
System.out.println( ); 会在输出完毕后自动换行 System.out.print( ); 在输出完毕后不会自动换行 MyEclipse/Eclipse快捷键: 定位到某一行, ...
- Vue项目引入sass
最近两天手头的事情暂时搞完了,可以抽出空来学习一下东西,之前项目都是鹏哥搭建好了,我们在直接在里面写代码,sass语法用来写样式还是比较方便常用的,今天就来试试怎么引入和配置sass 参考文章:Vue ...
- 使用jquery Ajax异步刷新 下拉框
一个下拉框 <label>产品类型:</label> <select id="protype" name="protype" on ...
- shell位置参数和专用参数举例
- celery中配置redis密码时的ValueError: invalid literal for int() with base 10: 'xxxx'
原配置: celery_broker = 'redis://:xxxx#xxxx@172.17.0.1:6379/0' # docker0 错误原因: 密码中不能有 # ? 等特殊字符 (无语O__O ...
- Codeforces Round #552:G. Minimum Possible LCM
官方题解是时间复杂度为O(nd)的.这里给出一个简单实现但是时间复杂度为O(NlogN) (N=1e7) 因为 a*b/gcd(a,b)=lcm(a,b) 所以我们可以枚举每一个因子,然后找到存在这个 ...
- Codeforces 1163E 高斯消元 + dfs
题意:给你一个集合,让你构造一个长度尽量长的排列,使得排列中任意相邻两个位置的数XOR后是集合中的数. 思路:我们考虑枚举i, 然后判断集合中所有小于1 << i的数是否可以构成一组异或空 ...