题目链接
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;
}
}
京公网安备 11010502036488号