首页 > 其他分享 >[AGC005B] Minimum Sum 题解

[AGC005B] Minimum Sum 题解

时间:2024-08-06 16:42:29浏览次数:15  
标签:sz rs int 题解 Sum tr Minimum ls top

题目传送门

看到这道题很多人用单调栈,其实用笛卡尔树本质差不多,但是思维难度更小。

不知道笛卡尔树的同学可以看这里

简单说来,笛卡尔树的一个子树可以代表一个区间,且左子树上点的下标小于根节点,右子树上点的坐标大于根节点。

这道题要求所有子区间的 \(\texttt{min}\) 值之和,其实就是看哪些子区间的最小值是同一个数,然后计算贡献,所以可以转换成一个树上问题。

我们先根据原序列建出一棵小根堆性质的笛卡尔树(注意树中存的是原序列的下标),这样根节点对应到原序列的值就是子树中的最小值了。

又由于上述性质,设当前根节点为 \(u\),左子树大小为 \(size_l\),右子树大小为 \(size_r\),问题其实变成了:求树上每个节点的 \(a[u]\times (size_l + 1)\times (size_r + 1)\) 之和。

为什么是这样呢?举个例子。

序列 \(\{4,1,3,5,2\}\) 建出来的笛卡尔树长这样:

(为了方便观察,这里直接呈现的是对应到序列中的值。)

先考虑节点 \(1\),要看有多少个子区间的最小值是它,相当于是看多少对节点的 LCA 是它,根据乘法原理,\(1\) 的贡献就为 \(1\times (1 + 1)\times (3 + 1) = 8\)。事实上确实有 \(8\) 个子区间的最小值是它。

这里 \(+1\) 是因为区间长度可以为 \(1\),也就是只有它自己。

同理,\(4\) 的贡献为 \(4\),\(2\) 的贡献为 \(6\),\(3\) 的贡献为 \(6\),\(5\) 的贡献为 \(5\),加起来总共为 \(29\)。

\(\texttt{Code:}\)

#include <iostream>

using namespace std;

const int N = 200010;
typedef long long ll;
int n;
int a[N];
struct node{
    int ls, rs;
}tr[N];
int root;
int stk[N], top;
ll res;
int sz[N];

void build() {
    for(int i = 1; i <= n; i++) {
        int las = 0;
        while(top > 0 && a[stk[top]] >= a[i]) las = stk[top--]; //单调栈优化 O(n) 建树
        if(!top) root = i;
        if(top) tr[stk[top]].rs = i;
        tr[i].ls = las;
        stk[++top] = i;
    }
}

void dfs(int u) {
    sz[u] = 1;
    if(tr[u].ls) dfs(tr[u].ls);
    if(tr[u].rs) dfs(tr[u].rs);
    sz[u] += sz[tr[u].ls] + sz[tr[u].rs];
    res += 1ll * a[u] * (sz[tr[u].ls] + 1) * (sz[tr[u].rs] + 1);
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(); //建树
    dfs(root); //算贡献
    printf("%lld", res);

    return 0;
}

标签:sz,rs,int,题解,Sum,tr,Minimum,ls,top
From: https://www.cnblogs.com/Brilliant11001/p/18345498

相关文章

  • 迟钝的舞会 题解
    题目id:1329题目描述牛是公认的笨拙的舞者。然后,约翰发现富有音乐细胞的母牛能产更多的奶。因此,他把他的整圈的牛都拉进了舞蹈培训班,包括所有的公牛(因为跳舞的时候得一男一女-_-)。这些牛正好有\(n\)头是公的,有\(n\)头是母的。在第一堂课开始之前,舞蹈老师想将他们分成一对一对的(......
  • 14. a+aa+...=sum
    题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。代码:#include<stdio.h>#include<stdlib.h>voidtest(){intsum=0;inta;inttemp;intn;scanf("%d%d",&a,&......
  • 08-04 题解
    08-03题解A根据题目的提示,发现所有数的积是不变的(\(gcd(a,b)*lcm(a,b)=a*b\)),所以差大和大简易证明设\(g=gcd(a,b)\),则\(a=a'g,\)\(b=b'g\),\(lcm(a,b)=a'b'g\)\(gcd(a,b)+lcm(a,b)=g(1+a'b')\)\(a+b=g(a'......
  • 08-02 题解
    <head><scriptsrc="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"type="text/javascript"></script><scripttype="text/x-mathjax-config">MathJax.Hub.Co......
  • ARC152C 题解
    blog。可能是很简单的,但是我实在是不会这种神秘题/ll/ll。Conclusion1.记\(d=a_n-a_1\),则极差始终等于\(d\)。证明显然。Conclusion2.操作极值时,最小值始终变化为\(d\),并且可以进行无限次这样的变化。证明显然。题意转变:最小化\((\texttt{最小值}\bmodd)\),且最小......
  • AISING2020E 题解
    blog。没题解就来写一篇捏。显然\(L_i>R_i\)的人都想去左边(记为LFT人),\(L_i<R_i\)的人都想去右边(记为RHT人),\(L_i=R_i\)的人可以摆烂。(LFT人与RHT人互相干扰,很难刻画。于是找性质。)存在最优方案,使得所有LFT人都在RHT人的左边。证明:如果有RHT人在LFT人的左边,......
  • pbootcms网站后台关闭验证码后, 无法登录问题解决方法
    最近闲来无事,在后台将pbootcms的登录验证码关闭了(全局配置-配置参数-安全配置-后台验证码)结果问题来了,第二天登录后台一直提示验证码不能为空。 这不是自己给自己找事吗!现在想输入验证码,也没有地方输入。 从程序上解决吧 apps\admin\controller\IndexController.ph......
  • 【题解】Solution Set - 新高一矩阵选讲「陶治霖」
    新高一矩阵选讲「陶治霖」https://www.becoder.com.cn/contest/5348「CF1970E3」Trails(Hard)考虑DP。定义\(f_{i,j}\)表示,第\(i\)天走到\(j\)的方案数。有转移:\[f_{i,j}=\sum_{k=1}^mf_{i-1,k}\times(s_jl_k+s_kl_j+s_js_k)\]https://www.luogu.com.cn/article/i......
  • CF568E Longest Increasing Subsequence 题解
    Description给定一个长度为\(n\)的有\(k\)个空缺的序列。你有\(m\)个数可以用于填补空缺。要求最大化最长上升子序列的长度。\(n,m\le10^5\),\(k\le10^3\)。Solution容易发现只需要先构造出LIS上的位置的值,对于其余未填位置随便填,所以构造LIS时就不需要考虑出......
  • 题解 P6873 [COCI2013-2014#6] FONT
    link题意给你\(N\)个单词,问最多能组成多少个包含所有小写英文字母的句子。\(\mathrm{Solution}\)\(N\le25\)显然搜索。枚举当前选还是不选,搜到头判断是否成功即可。\(\mathrm{Code}\)#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;consti......