习题:木桩涂涂看
n n 个木桩排成一排,从左到右依次编号为 。每次给定 2 2 个整数 , b b (),蒜头君便骑上他的电动车从木桩 a a 开始到木桩 依次给每个木桩涂一次颜色。但是 n n 次以后 lele 已经忘记了第 个木桩已经涂过几次颜色了,你能帮他算出每个木桩被涂过几次颜色吗?
输入格式
第一行是一个整数 n n ()。
接下来的 n n 行,每行包括两个整数 a, b ()。
输出格式
n n 个整数,第 个数代表第 i i <script type="math/tex" id="MathJax-Element-714">i</script> 个木桩总共被涂色的次数。
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 100005;
int C1[maxn] = {}, C2[maxn] = {};
int n;
void update(int x, int y)
{
while (x <= n) {
C1[x]++;
x += (x & -x);
}
while (y <= n) {
C2[y]++;
y += (y & -y);
}
}
int getSum(int x)
{
int sum1 = 0, sum2 = 0, tmp = x;
while (tmp >= 1) {
sum1 += C1[tmp];
tmp -= (tmp & -tmp);
}
tmp = x - 1;
while (tmp >= 1) {
sum2 += C2[tmp];
tmp -= (tmp & -tmp);
}
return sum1 - sum2;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; ++i) {
int x, y;
cin >> x >> y;
update(x, y);
}
for (int i = 1; i <= n; ++i) {
cout << getSum(i) << (i == n ? "":" ");
}
}
代码2: 树状数组+差分
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int n, C[100005] = {};
void update(int x, int val)
{
for (; x <= n; x += (x & -x)) {
C[x] += val;
}
}
int getSum(int x)
{
int sum = 0;
for (; x >= 1; x -= (x & -x)) {
sum += C[x];
}
return sum;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; ++i) {
int x, y;
cin >> x >> y;
update(x, 1);
update(y + 1, -1);
}
for (int i = 1; i <= n; ++i) {
cout << getSum(i) << (i == n ? "":" ");
}
}