cf1151e number of components

很常见的思想:将整体求改为统计每个部分的贡献

本题中统计[l, r]时, 每个连通块有一个重要特征, 最右端的数在[l,r]中而下一个数不在(好像是句废话

那么我们分别考虑每个点对连通块的贡献, 即它是某个连通块的右端点, 这样可以保证每个连通块只会被算一次

对于序列 \(a_1a_2\cdots a_n\)\(a_i < a_{i+1}\) l的范围是1~\(a_i\) r的范围是\(a_i\) ~ $ a_j-1$ ans += (a[i+1] - a[i]) * a[i];

否则 同理 ans += (n-a[i]+1) * (a[i] - a[i+1]);

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
template <typename T>
void read(T &x) {
    x = 0;int f = 1;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    x *= f;
}
const int N = 100050;
ll n, a[N], ans;
int main() {
    read(n);
    for (int i = 1;i <= n; i++) read(a[i]);
    for (int i = 1;i <= n; i++) {
        if (a[i+1] > a[i]) 
            ans += (a[i+1] - a[i]) * a[i];
        else ans += (n-a[i]+1) * (a[i] - a[i+1]);
    }
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Hs-black/p/11739937.html