依旧是树状数组,只不过题意是区间修改,单点查询
网上的模板的写法感觉很不直观,按照自己的理解写了,和模板不太一样不过也A了
其实可以转化为区间查询单点修改。
一次[a,b,+1]的修改可以拆分为[1,b,+1]和[1,a-1,-1]两个修改,这样就转化为所有修改都是[1, i]这种了
令arr[i]表示对[1, i]的修改的累加值
则所求i涂色几次求的就是arr[i]+arr[i+1]+...+arr[n]([1, p](p < i)这种修改是影响不到arr[i]的)
即常规树状数组的query(n)-query(i-1)
问题就可以解决了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110000;
int tree[maxn], n;
int lowbit(int x)
{
return x & -x;
}
int query(int pos)
{
if (pos == 0)
return 0;
int ret = 0;
while (pos) {
ret += tree[pos];
pos -= lowbit(pos);
}
return ret;
}
void update(int pos, int delta)
{
if (pos == 0)
return;
while (pos <= n) {
tree[pos] += delta;
pos += lowbit(pos);
}
}
int main()
{
while (~scanf("%d", &n) && n) {
memset(tree, 0, sizeof(tree));
for (int i = 1; i <= n; i++) {
int fr, to;
scanf("%d%d", &fr, &to);
update(to, 1);
update(fr-1, -1);
}
for (int i = 1; i <= n; i++)
printf("%d%c", query(n) - query(i-1), (i == n) ? '\n' : ' ');
}
return 0;
}