首页 > 其他分享 >qoj8542 Add One 2 题解

qoj8542 Add One 2 题解

时间:2024-06-22 17:03:42浏览次数:14  
标签:cnt ch 题解 top Add stk qoj8542 序列 define

题目链接

点击打开链接

题目解法

我们先考虑什么样的序列 \(x_1,...,x_n\) 是可以被得到的
对于 \(x_i>x_{i+1}\) 的位置,我们需要至少对前缀 \([1,i]\) 做 \(x_i-x_{i+1}\) 次操作;对于 \(x_{i-1}<x_{i}\) 的位置,我们需要至少对后缀 \([i,n]\) 做 \(x_i-x_{i-1}\) 次操作
我们需要最大利用这个性质,所以我们从后往前依次做前缀操作,再从前往后依次做后缀操作,这样操作完之后会得到 \(x_i\) 全部相同的序列,则当前序列合法的条件是操作完后序列中的数 \(\ge 0\)
形式化表示一下为:\(x_1-\sum\limits_{i=1}^{n-1}[x_i>x_{i+1}](x_i-x_{i+1})\ge 0\)(或 \(x_n-\sum\limits_{i=1}^{n-1}[x_i<x_{i+1}](x_{i+1}-x_i)\ge 0\),这两个式子是等价的)

令 \(x_0=x_{n+1}=inf\)
即条件为 \(\sum\limits_{i=0}^{n}|x_i-x_{i+1}|\le 2\times inf\)(就是把上面的限制翻一倍)

我们考虑在原来的序列上单点加,使其满足条件,要求最小化序列和
可以发现,将满足 \(\max\limits_{i=l}^r\{x_i\}<\min\{x_{l-1},x_{r+1}\}\) 的 \([l,r]\) 全部 \(+1\),可以使左式的值 \(-2\)
用这个思路,我们考虑建出笛卡尔树,只要按照区间长度从小往大贪心做即可

时间复杂度 \(O(n\log n)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=1000010;
const LL inf=1e17;
int n,L[N],R[N];
LL a[N];
pii seq[N];
int stk[N],top;
void work(){
    read(n);
    F(i,1,n) read(a[i]);
    a[0]=a[n+1]=inf;
    LL tot=0;F(i,0,n) tot+=abs(a[i]-a[i+1]);
    stk[top=0]=-1;
    F(i,0,n+1){
        while(top&&a[i]>=a[stk[top]]) top--;
        L[i]=stk[top]+1,stk[++top]=i;
    }
    stk[top=0]=n+2;
    DF(i,n+1,0){
        while(top&&a[i]>a[stk[top]]) top--;
        R[i]=stk[top]-1,stk[++top]=i;
    }
    int cnt=0;
    F(i,1,n){
        if(L[i]==1&&R[i]==n) continue;
        if(L[i]>1&&(R[i]==n||R[L[i]-1]==R[i])) seq[++cnt]={R[i]-L[i]+1,a[L[i]-1]-a[i]};
        else seq[++cnt]={R[i]-L[i]+1,a[R[i]+1]-a[i]};
    }
    sort(seq+1,seq+cnt+1);
    LL ans=0;
    F(i,1,cnt){
        if(tot<=2*inf) break;
        auto [x,y]=seq[i];
        if(tot-2*y<=2*inf) ans+=((tot-2*inf)/2)*x,tot=2*inf;
        else ans+=1ll*x*y,tot-=2*y;
    }
    F(i,1,n) ans+=a[i];
    printf("%lld\n",ans);
}
int main(){
    int T;read(T);
    while(T--) work();
    return 0;
}

标签:cnt,ch,题解,top,Add,stk,qoj8542,序列,define
From: https://www.cnblogs.com/Farmer-djx/p/18262482

相关文章

  • AUCell和AddModuleScore函数进行基因集评分
    AUCell和AddModuleScore分析是两种主流的用于单细胞RNA测序数据的基因集活性分析的方法。这些基因集可以来自文献、数据库或者根据具体研究问题进行自行定义。AUCell分析原理:1、AUCell分析可以将细胞中的所有基因按表达量进行排序,生成一个基因排名列表,表达量越高的基因排名......
  • [集训队互测 2023] 树哈希 题解报告
    [集训队互测2023]树哈希题解报告/bx/bx/bxzky!!!题意给定常数\(q\),定义一棵以\(1\)为根的有根树\(T\)的\(s(T)\)为\(T\)中本质不同的子树数量,定义其权值为\(q^{s(T)}\)。给定\(n\),对于\(i=1,\dots,n\)求所有大小为\(i\)的有标号有根树的权值之和对\(P\)......
  • CF1978E Computing Machine 题解
    好写程度:\(E>D>C\)。好想程度:\(C>D=E\)。总结:C是全场最难。我们考虑把两个操作对全体的\(a_i,b_i\)都做一遍,会发现我们只会做这两遍,不会再有嵌套的了,因为都做过一遍后\(\{a\}\)中0的数量只会减少,而且即使再做一遍也无法给\(\{b\}\)改成不一样的了,比较显然。下文中令......
  • [题解]AT_abc267_f [ABC267F] Exactly K Steps
    大家好,我是毒瘤,喜欢用玄学算法过题。发现题解区没有这个做法,于是来发一篇。思路不难发现如果一个点对\((u,v)\)的距离为\(d\),那么在这棵树以\(u\)为根时,\(v\)的深度为\(d\)。于是考虑换根DP。首先思考如何计算答案。显然我们可以将查询离线下来,然后当换根到以\(u\)......
  • caddy 模块(module) caddyhttp Start启动逻辑分析
     ./modules/caddyhttp/app.gofunc(app*App)Start()error{//xx} Start方法属于一个自定义的App结构体,用于启动应用程序中的多个HTTP服务器实例。下面是对该方法的主要逻辑和关键步骤的详细分析:1.日志设置:首先,通过zap.NewStdLogAt创建一个兼容......
  • BD202301·公园题解
    BD202301·公园题解考虑将整个移动过程分为两个部分:小度和度度熊汇合之前小度和度度熊汇合之后第一部分可以直接用Dijkstra算法直接搞定,第二部分可以考虑反向思考,从N点出发做一次Dijkstra,最后枚举每个汇合点即可得到答案。时间复杂度\(\Theta(nlogn)\)代码如下:#include......
  • [题解]AT_abc264_e [ABC264E] Blackout 2
    思路一道很经典的题,运用了一种叫「时光倒流」的技巧。「时光倒流」本质上就是将所有删边(或删点)的操作,通过倒序循环求值的方式转化为加边(或加点)。「时光倒流」具体实现通常伴随着并查集出现,维护一个连通块的某种性质。首先,我们需要将所有从始至终没有删过的边加入并查集。在这......
  • [题解]AT_abc263_d [ABC263D] Left Right Operation
    思路首先,不难发现最终的序列一定是形如下面的序列:\[l,\dots,l,a_i,a_{i+1},\dots,a_{i+j},r,\dotsr\]那么,我们就可以将其分为三段,每段都单独维护。首先,对于第一段,我们可以枚举出最后一个\(l\)的位置\(x\),那么和为\(x\timesl\)。对于第二段显然可以用前......
  • [题解]AT_abc256_h [ABC256Ex] I like Query Problem
    思路首先可以看一下P4145,在P4145中使用了一种叫势能线段树的Trick。对于势能线段树,我个人的理解是,对于一段区间(或一个点)直接暴力维护,在经过很少的次数后操作将没有意义的题就可以使用势能线段树。在本题中,如果没有推平操作,显然我们可以直接使用势能线段树,时间复杂度可以轻......
  • [题解]AT_abc263_f [ABC263F] Tournament
    先为大家毙掉一个错解思路首先不难发现,如果将整棵比赛的对战图画出来,一定是一个满二叉树。不妨将令一个节点\(u\)的左右儿子编号分别为\(2u\)和\(2u+1\)。然后定义\(dp_{u,d}\)表示将\(u\)为根的子树内的选手全部比赛完,并且\(u\)已经赢了\(d\)场的最大结果。发......