zoukankan      html  css  js  c++  java
  • 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);
    } 
    

      

  • 相关阅读:
    OLAP ODS项目的总结 平台选型,架构确定
    ORACLE ORA12520
    ORACLE管道函数
    ORACLE RAC JDBC 配置
    ORACLE RAC OCFS连接产生的错误
    ORACLE 启动和关闭详解
    OLAP ODS项目的总结 起步阶段
    ORACLE RAC 配置更改IP
    ORACLE RAC OCR cann't Access
    ORACLE RAC Debug 之路 CRS0184错误与CRS初始化
  • 原文地址:https://www.cnblogs.com/pkgunboat/p/10815980.html
Copyright © 2011-2022 走看看