差分

基础知识:

  一维差分:

        给区间[l, r]中的每个数加上c

        B[ l ]  +=  c, B[ r + 1 ]  -= c

   二维差分:

        给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c

        S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c

   差分数组恢复成原数组只和原数组的第一个元素与差分数组全部元素相关。

 

1.增减序列

  题目链接:https://www.acwing.com/problem/content/102/ (算法竞赛进阶指南)

   思路:求出差分序列,正数和负数可以组成一组,每一次的操作可以使得正数减一负数加一,如果正数和负数总数不同,在用完其中之一以后单独对正数或负数进行调整。

      tips: 在差分序列中想要把1变成0可以有两种操作,可以将前面的数字加一,或者该数字减一,所以可以有2种结果。如果把K 变成0,最终有 K + 1种结果。

   代码:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
typedef long long LL;

int a[N];

int main()
{
    int n;
    cin >> n;
    
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    
    for(int i = n; i > 1; i--)
    {
        a[i] -= a[i - 1];
    }
    
    LL pos = 0, neg = 0;
    for(int i = 2; i <= n; i++)
    {
        if(a[i] > 0) pos += a[i];
        else neg -= a[i];
    }
    
    cout << min(pos, neg) + abs(pos - neg) << endl;
    cout << abs(pos - neg) + 1 << endl;
    
    return 0;
}

 

2.最高的牛

  题目链接:https://www.acwing.com/problem/content/103/ (算法竞赛进阶指南)

   思路:先使用差分数组将所有牛的高度都设置成最高,每次根据输入将区间中牛的身高降低,最后根据差分数组求原数组

   代码:

 

#include <iostream>
#include <set>

using namespace std;

const int N = 10010;

int height[N];

int main()
{
    int n, p, h, m;
    cin >> n >> p >> h >> m;
    
    height[1] = h;
    
    set<pair<int, int>> existed;
    
    for(int i = 0, a, b; i < m; i++ )
    {
        cin >> a >> b;
        if(a > b) swap(a, b);
        if(!existed.count({a, b}))
        {
            existed.insert({a, b});
            
            //将[a + 1, b - 1]之间的数字减一
            height[a + 1]--;
            height[b]++;
        }
    }
    
    for(int i = 1; i <= n; i++)
    {
        height[i] += height[i - 1];
        cout << height[i] << endl;
    }
    
    return 0;
}

 

posted @ 2020-08-10 06:12  锤子科技未来产品经理  阅读(168)  评论(0)    收藏  举报