这题用线段树的话简直就是一个水题。。不过刚学树状数组,要用一下。
题意:每次给你a,b,表明a~b之间涂色,然后最后一次输出每个气球被涂色的次数。
要用树状数组就要考虑怎么转化为前缀和问题,这题可以这样做:每次输入a,b,令A[a] = 1,A[b+1] = -1; 然后更新和,查询的时候容易知:a~b之间都被涂了一次,求前缀和结果也为一次,多次插入a,b,性质不变,插入后即可直接输出。复杂度很小,这也是树状数组的好处。。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 100100 int c[N]; int n; int lowbit(int k) { return k&(-k); } void insert(int k,int num) { while(k<=n) { c[k] += num; k += lowbit(k); } } int getsum(int k) { int sum = 0; while(k>0) { sum += c[k]; k -= lowbit(k); } return sum; } void init() { int a,b,i; memset(c,0,sizeof(c)); for(i=1;i<=n;i++) { scanf("%d%d",&a,&b); insert(a,1); insert(b+1,-1); } } int main() { int j; while(cin>>n && n) { init(); for(j=1;j<n;j++) { cout<<getsum(j)<<" "; } cout<<getsum(j)<<endl; } return 0; }
代码参考了:http://blog.csdn.net/lulipeng_cpp/article/details/7816527