Codeforces Round #553 (Div. 2) E. Guess the Root(dp单点算贡献)

题目链接:https://codeforces.com/contest/1151/problem/E

题意:现在又一条链,每个节点上有个值 A i A_{i} Ai,现在你需要枚举所有值的区间,如果节点值在区间中保留节点,然后将形成的连通块个数加起来。

解题心得:

  1. 看见一个大佬说的很好,看见这种很多连续区间组合求值的问题,其实就是一个单点算贡献的问题。
  2. 枚举每一个节点作为当前连通块左节点能有多少个连续值的区间来表达。
  3. A i > A i − 1 A_{i}>A_{i-1} Ai>Ai1,那么 A i A_{i} Ai作为连通块的左起点,在区间取值左边可以取 [ A i − 1 + 1 , A i ] [A_{i-1} + 1, A_{i}] [Ai1+1,Ai],区间右边取值可以取 [ A i , n ] [A_{i}, n] [Ai,n],总共的取法总数就是 ( A i − A i − 1 ) ∗ ( n − A i + 1 ) (A_{i}-A_{i-1})*(n-A_{i}+1) (AiAi1)(nAi+1)
  4. A i &lt; A i − 1 A_{i}&lt;A_{i-1} Ai<Ai1,那么 A i A_{i} Ai作为连通块的左起点,在区间取值左边可以取 [ A i , A i − 1 − 1 ] [A_{i} , A_{i-1}-1] [Ai,Ai11],区间右边取值可以取 [ 1 , A i ] [1, A_{i}] [1,Ai],总共的取法总数就是 ( A i − 1 − A i ) ∗ A i (A_{i-1}-A_{i})*A_{i} (Ai1Ai)Ai
  5. A i = A i − 1 A_{i}=A_{i-1} Ai=Ai1 A i A_{i} Ai不可能作为连通块的左端点被取到。


#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+100;
typedef long long ll;

int num[maxn], n;

int main() {
    //freopen("1.in", "r", stdin);
    scanf("%d", &n);
    for(int i=1;i<=n;i++) {
        scanf("%d", &num[i]);
    }

    ll ans = 0;
    for(int i=1;i<=n;i++) {
        if(num[i] > num[i-1]) {
            ans = ans + 1ll * (num[i] - num[i-1]) * (n- num[i] + 1);
        } else if(num[i] < num[i-1]) {
            ans = ans + 1ll * (num[i-1] - num[i]) * num[i];
        }
    }

    cout<<ans<<endl;

    retu
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值