HDU 1556:http://acm.hdu.edu.cn/showproblem.php?pid=1556
题目大意:给出一个N,表示数字从1到N,然后会给出N个区间,对N个区间作加1操作。最后分别输出N个数字,它们各自的值。N最大100000
简单的说,就是,区间更新,单点求值。
树状数组的功能,就是,向左走,是查询区间和;向右走,是更新单点值,而维护树状数组。
放假在家,思维僵硬。于是我有一个想法,如果将树状数组反过来用,就可以实现 向左走,更新区间值,而维护树状数组;向右走,是查询单点值。 结果可以过,小激动
实际上,还是 向左是对区间操作,向右是对单点操作。
其实还是基础题,裸的树状数组应用,可以用来加深对树状数组的理解。
接下来就上代码了,和普通的树状数组其实就是 add更新操作和 query查询操作变化一下啦。
#include "bits/stdc++.h"
using namespace std;
#define inf 100009
#define INF 999999999
#define ll long long
int c[inf];
int n;
void init()
{
memset(c,0,sizeof c);
}
int lowbit(int i)
{
return i&-i;
}
void add(int i,int tag) //区间1到n加tag
{
while(i>0)
{
c[i]+=tag;
i-=lowbit(i);
}
}
ll query(int i)
{
ll sum=0;
while(i<=n)
{
sum+=(ll)c[i];
i+=lowbit(i);
}
return sum;
}
int main()
{
int i,a,b;
while(~scanf("%d",&n)&&n)
{
init();
for(i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
add(b,1);
add(a-1,-1);
}
for(i=1;i<n;i++)
printf("%lld ",query(i));
printf("%lld\n",query(i));
}
return 0;
}