题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1556
题目大意:
N个气球排成一排,从左到右编号为1~N,给N组数据,每次给2两个整数s,e,表示从s到e将
气球涂色。当涂到N次以后已经忘记了第i个气球被涂过几次颜色了。现在来计算出每个气球被
涂了几次颜色,并输出出来。
思路:
典型的更新区间,单点求值问题。直接模拟会超时,考虑用树状数组来做。单点更新中,树状
数组表示区间的和。在区间更新中,树状数组表示单个元素的变化。
这道题中,区间(s,e)加1表示将s到e的气球涂色,先进行操作Update(s,1),表示将s~N个气
球全部涂一次颜色,再进行操作Update(e+1,-1),表示将e+1的气球去除一次涂色。这样就
表示将区间(s,e)的气球涂色了。查询Query(i)表示第i个气球被涂颜色的次数。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 100010; int N,Tree[MAXN]; int Lowbit(int i) { return i & (-i); } void Updata(int i,int x) { while(i <= N) { Tree[i] = Tree[i] + x; i = i + Lowbit(i); } } int Query(int n) { int sum = 0; while(n > 0) { sum += Tree[n]; n = n - Lowbit(n); } return sum; } int main() { while(cin >> N && N) { memset(Tree,0,sizeof(Tree)); for(int i = 0; i < N; ++i) { int s,e; cin >> s >> e; Updata(s,1); Updata(e+1,-1); } for(int i = 1; i < N; ++i) printf("%d ",Query(i)); printf("%d\n",Query(N)); } return 0; }
时间: 2024-10-22 11:31:25