hdu 1556 http://acm.hdu.edu.cn/showproblem.php?pid=1556
这题跟 hdu 1166 就刚好相反。具体看代码吧。
1 /* 2 hdu 1556 Color the ball 3 该段求点 4 整个过程和 该点求段是相反的 查询向上,更新向下 5 更新过程就是将管辖到我们涂色区间的节点数值加一,这样最后,往上查询,把这些节点求和即可 6 https://www.cnblogs.com/zichi/p/4807072.html 7 */ 8 #include <iostream> 9 #include <stdio.h> 10 #include <cstring> 11 #define MAX 100010 12 using namespace std; 13 int tree[MAX]; 14 int arr[MAX]; 15 int n; 16 17 int lowbit(int x){return x&(-x);} 18 19 void update(int x,int val) //更新,我们向下更新,相当于将管辖 1 到 x 的所有节点加val 20 { //只要看看,树状数组,减一个lowbit(i)到哪个节点,就能理解了 21 for (int i=x;i>0;i-=lowbit(i)) 22 tree[i]+=val; 23 } 24 25 int Query(int x)//查询时,查询x被涂的次数,我们向上将包含它的节点累加就是答案 26 { 27 int ans = 0; 28 for (int i = x;i<=n;i+=lowbit(i)) 29 ans+=tree[i]; 30 return ans; 31 } 32 33 34 int main () 35 { 36 int a,b; 37 while(~scanf ("%d",&n) && n) 38 { memset(tree,0,sizeof(tree)); 39 for (int i=1;i<=n;++i) 40 { 41 scanf ("%d%d",&a,&b); 42 update(b,1); 43 update(a-1,-1);//这里通过这样更新的方式,实现了一段区间的加一 44 } 45 for (int i=1;i<=n;++i) 46 { 47 printf ("%d",Query(i));//然后直接查询,就可以得到该点被涂次数 48 if(i!=n) printf (" "); 49 } 50 printf (" "); 51 } 52 }