题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1556
解题思路
方法一:差分与前缀和
差分与前缀和
这应该是入门学的吧。
为了回忆回忆加深一下印象,再稍微写一下。
区间[a,b]全部+1,就让存差值的数组c在a位置+1,b+1的位置-1。
c[i]=第i个数的值-第i-1个数的值。
输出i位置的值,求i位置的前缀和就行了。
AC代码
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int ball[N]; int n; int main(){ while(cin>>n&&n){ memset(ball,0,sizeof ball); for(int i=1;i<=n;i++){ int a,b; cin>>a>>b; ball[a]++; ball[b+1]--; } for(int i=1;i<=n;i++) ball[i]+=ball[i-1]; for(int i=1;i<n;i++) cout<<ball[i]<<' '; cout<<ball[n]<<endl;//题目没说,但是好像要求输出结尾不能有空格,有空格没法AC } }
方法二:树状数组
区间修改,单点查询:
getsum用于求前缀和;update用于更改端点的值;
本质上,与差分前缀和是一样的。
差分思想,通过树状数组体现!
AC代码
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int c[N],n; int lowbit(int x){ return x&(-x); } void update(int x,int add){ while(x<=n){ c[x]+=add; x+=lowbit(x); } } int getsum(int x){ int ans=0; while(x>0){ ans+=c[x]; x-=lowbit(x); } return ans; } int main(){ int a,b; while(cin>>n&&n){ memset(c,0,sizeof c); for(int i=1;i<=n;i++){ cin>>a>>b; update(a,1); update(b+1,-1); } for(int i=1;i<n;i++) cout<<getsum(i)<<' '; cout<<getsum(n)<<endl; } }