题意
传送门 POJ 3263
题解
BIT
当 A A A 看得到 B B B 时,区间 ( A , B ) (A,B) (A,B) 内所有元素的可能的最大值都为 m i n ( A , B ) − 1 min(A,B)-1 min(A,B)−1;那么 B I T BIT BIT 维护区间被覆盖的次数,对于每个索引 i i i,可能的最高高度为 H − s u m ( i ) H-sum(i) H−sum(i)。注意处理区间重复的情况。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 10005
int rec[maxn][maxn], bit[maxn], N, I, H, R;
void add(int i, int x)
{
while (i <= N)
{
bit[i] += x;
i += i & -i;
}
}
int sum(int i)
{
int s = 0;
while (i > 0)
{
s += bit[i];
i -= i & -i;
}
return s;
}
int main()
{
scanf("%d%d%d%d", &N, &I, &H, &R);
while (R--)
{
int a, b;
scanf("%d%d", &a, &b);
if (a > b) swap(a, b);
if (rec[a][b] == 1) continue;
rec[a][b] = 1;
add(a + 1, 1);
add(b, -1);
}
for (int i = 1; i <= N; i++)
{
printf("%d\n", H - sum(i));
}
return 0;
}
差分
差分将对区间的操作转换为区间端点的操作,最后通过计算前缀和求解。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
using namespace std;
#define maxn 10005
typedef pair<int, int> P;
set<P> used;
int N, I, H, R, sum[maxn];
int main()
{
scanf("%d%d%d%d", &N, &I, &H, &R);
for (int i = 0; i < R; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
if (a > b)
swap(a, b);
if (used.find(P(a, b)) != used.end())
continue;
--sum[a + 1], ++sum[b];
used.insert(P(a, b));
}
for (int i = 1; i <= N; ++i)
{
sum[i] += sum[i - 1];
printf("%d\n", H + sum[i]);
}
return 0;
}