题目链接: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]); //} }