• Codeforces 1151E 统计贡献


    题意:给你一个数组a,设函数f(l, r)为数组a中权值在[l, r]之间的连通块的数目,比如a = [1, 3, 2, 1], f(1, 2) = 2, 连通块是位置1和位置3,4。问Σ(i = 1 to n)(j = i to n) f(i, j)的和是多少。

    思路:这种求各种情况的总答案的问题,一种常见的思路是计算每种子问题对所有情况的贡献,这样只需对每个子问题计算即可。对于这个问题,假设i位置为1个连通块的左边界,我们计算一下它对答案的贡献。

    1:若a[i - 1] < a[i], 那么为保证i是左边界,那么l必须在(a[i - 1], a[i]]这个范围内,r在[a[i], n]就可以了。

    2:若a[i - 1] >= a[i], 那么r必须在[a[i], a[i - 1])这个范围内,l在[1, a[i]]内。

    但是只统计左边界答案可能是不对的,因为有些值可能压根不存在,所以我们还要统计右边界,这样每个连通块被计算了两次,答案除以二就可以了。

    代码:

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn = 100010;
    LL a[maxn];
    int main() {
    	int n;
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a[i]);
    	}
    	LL ans = 0;
    	for (int i = 1; i <= n; i++) {
    		if(a[i - 1] < a[i]) ans += (a[i] - a[i - 1]) * (n - a[i] + 1);
    		else ans += (a[i - 1] - a[i]) * a[i];
    		if(a[i + 1] < a[i]) ans += (a[i] - a[i + 1]) * (n - a[i] + 1);
    		else ans += (a[i + 1] - a[i]) * a[i]; 
    	}
    	printf("%lld
    ", ans / 2);
    } 
    

      

  • 相关阅读:
    图解JQUERY尺寸及位置定义
    JS中offsetTop、clientTop、scrollTop、offsetTop各属性介绍
    js拖拽的封装
    Git详解之九:Git内部原理
    Git详解之八:Git与其他系统
    量化投资的Python库——Tushare
    Python数据分析-Day2-Pandas模块
    Python数据分析-Day1-Numpy模块
    Python全栈开发-Day8-Socket网络编程
    Python全栈开发-Day7-面向对象编程2
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10815980.html
Copyright © 2020-2023  润新知