题目
已知有若干头牛,且最高的牛为 h h h,两头牛能互相看见当且仅当中间的牛矮于两头牛,可以知道某些互相看见的关系,问每头牛的最高身高是多少
分析
若现在为第
x
x
x头牛和第
y
y
y头牛能相互看见
首先特判的情况,
x
>
y
(
交
换
)
x>y(交换)
x>y(交换)或
x
x
x和
y
y
y这种关系出现过(不需要进行(重复的可以用map库))
之后那可以在
x
+
1
x+1
x+1和
y
−
1
y-1
y−1的牛中各减少1的身高(初始身高为h)
问题是会超时,那可以用一种类似于前缀和的方式,在a+1的地方减少1,在b的地方增加1,前缀和后就会形成
x | x+1 | x+2 | … | y-2 | y-1 | y | y+1 | y+2 |
---|---|---|---|---|---|---|---|---|
0 | -1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | -1 | -1 | -1 | -1 | -1 | 0 | 0 | 0 |
然后就简单了,再提一点树状数组的区间修改类似于这种方法,所以特意标记为树状数组
代码
#include <cstdio>
#include <map>
using namespace std;
int n,h,m,a,b,s[10001];
map<pair<int,int>,bool>inp;
int main(){
scanf("%d%*d%d%d",&n,&h,&m);
while (m--){
scanf("%d%d",&a,&b);
if (a>b) a^=b,b^=a,a^=b;//交换
if (inp[make_pair(a,b)]) continue;//存在过
s[a+1]--; s[b]++;
inp[make_pair(a,b)]=1;
}
for (int i=1;i<=n;i++){
s[i]+=s[i-1];
printf("%d\n",h+s[i]);
}
return 0;
}