算法竞赛进阶指南0x03 前缀和与差分

增减序列

    1. 决定序列元素的是差分的第一个元素
    2. 保证序列相等的是第二个到最后一个元素
    3. 最后一个元素+1没啥关系
#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e5+10;
int a[N];
LL d[N];
int main(){
    int n; cin >> n;
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++) d[i] = a[i] - a[i-1];
    LL cnt1 = 0, cnt2 = 0;
    for(int i = 2; i <= n; i ++){
        if(d[i] > 0) cnt1 += d[i];
        else if(d[i] < 0) cnt2 += -1 * d[i];
    } 
    cout << max(cnt1, cnt2) << endl << abs(cnt1 - cnt2) + 1 << endl;
    return 0;
}

最高的牛

  1. 之前疑惑在了一个点:l,r之间的全部减小一,假如中间本来就有更小的会不会减小多了呀,仔细一想,
    发现不会,因为需要全部减一维护中间的相对关系,不然中间的相对关系就错误了
#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 10010;
int d[N], s[N];
set< pair<int, int> > S;

int main(){
    int n, p, h, m; scanf("%d %d %d %d", &n, &p, &h, &m);
    d[1] = h, d[n + 1] = -h; 
    while(m --){
        int l, r; scanf("%d %d", &l, &r);
        if(l > r) swap(l, r);
        if(S.count({l, r})) continue;
        S.insert({l, r});
        d[l + 1] -= 1;
        d[r] += 1;
    }  
    for(int i = 1; i <= n; i ++) printf("%d\n", s[i] = s[i-1] + d[i]);
    return 0;
}

posted @ 2022-03-22 21:30  牛佳文  阅读(51)  评论(0编辑  收藏  举报