题目链接:https://vjudge.net/contest/381841#problem/B
题目描述:
有n头奶牛排成一列,现在告诉你最高的奶牛的序号以及它的身高,有R行表示i能看见j,i能看见j需要满足ij之间的牛的高度小于i的高度,且j的高度大于等于i的高度。输出每个奶牛的最大身高。
解题思路:
这题一看就是要用差分。i能看到j也就是ij之间的高度都至少比i的高度小1,那么s[i+1]--;s[j]++。然后最后求一个前缀和就完了。
本题有几个细节上的坑值得注意:
1.i可能大于j,差分的时候注意。
2.可能会有重复数据,比如之前说了i能看到j,后面有说了一遍i能看到j,你总不能再差分一遍吧。需要用一个map来记录(i,j)和(j,i)有没有被记录过。
小优化,就是最高的那头奶牛肯定到时候求前缀和的时候为0,因此,前缀和求到i时,直接s[i]+H,就可以得到i的高度。
代码:

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  
#include <climits>

using namespace std;
const int MAXN = 1e6+7;
int s[MAXN];
map<pair<int,int>, int> mp;
int main()
{
    int N, I, H, R;
    cin >> N >> I >> H >> R;
    for(int i = 1; i <= R; i++) {
        int A, B;
        scanf("%d%d",&A, &B);
        if(A > B) swap(A, B);
        if(mp[make_pair(A,B)] == 1) continue;
        mp[make_pair(A, B)] = 1;
        s[A+1]--;
        s[B]++;
    }
    for(int i = 1; i <= N; i++) {
        s[i] = s[i-1] + s[i];
        printf("%d\n",H+s[i]);
    }
    //for(int i = 1; i <= N; i++) {
    //    printf("%d\n",H+s[i]-s[I]);
    //}
}