Problem Description
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
Input
每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
当N = 0,输入结束。
当N = 0,输入结束。
Output
每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
Sample Input
3
1 1
2 2
3 3
3
1 1
1 2
1 3
0
Sample Output
1 1 1
3 2 1
Author
8600
Source
模板题:
线段树区间修改+单点查询
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<vector> #include<algorithm> #define N (1 << 19) using namespace std; void in(int &x){ register char c=getchar();x=0;int f=1; while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} x*=f; } int n,m,ans,X; struct node{ int l,r,w,f; }e[N]; void down(int k){ int f=e[k].f;e[k].f=0; e[k*2].f+=f;e[k*2+1].f+=f; e[k*2].w=(e[k*2].w+(e[k*2].r-e[k*2].l+1)*f); e[k*2+1].w=(e[k*2+1].w+(e[k*2+1].r-e[k*2+1].l+1)*f); } void build(int k,int l,int r){ e[k].l=l;e[k].r=r; if(l==r) return; int mid=(l+r)/2; build(k*2,l,mid);build(k*2+1,mid+1,r); } void change_interval(int k,int l,int r){ int ll=e[k].l,rr=e[k].r,mid=(ll+rr)/2; if(ll>=l&&rr<=r){ e[k].w=(e[k].w+(rr-ll+1)); e[k].f+=1;return; }if(e[k].f) down(k); if(l<=mid) change_interval(k*2,l,r); if(r>mid) change_interval(k*2+1,l,r); e[k].w=(e[k*2].w+e[k*2+1].w); } void ask_point(int k){ int ll=e[k].l,rr=e[k].r,mid=(ll+rr)/2; if(ll==rr){ ll==n?printf("%d ",e[k].w):printf("%d ",e[k].w); return; }if(e[k].f) down(k); ask_point(k*2);ask_point(k*2+1); e[k].w=(e[k*2].w+e[k*2+1].w); } int main() { while(1){ in(n); if(!n) break; memset(e,0,sizeof(e)); build(1,1,n); for(int l,r,i=1;i<=n;i++){ in(l);in(r); change_interval(1,l,r); }ask_point(1); }return 0; }
树状数组区间修改+单点查询
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #include<algorithm> #include<stack> #include<vector> using namespace std; void in(int &x){ register char c=getchar();x=0;int f=1; while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} x*=f; } //树状数组区间修改+单点查询 const int N =1 << 19; int bit[N],n; int lowbit(int k){ return k&-k; } void add(int k,int num){ while(k<=n){ bit[k]+=num; k+=lowbit(k); } } int ask(int k){ int sum=0; while(k>0){ sum+=bit[k]; k-=lowbit(k); }return sum; } int main() { while(1){ in(n); if(!n) break; memset(bit,0,sizeof(bit)); for(int l,r,i=1;i<=n;i++){ in(l);in(r); add(l,1);add(r+1,-1); }for(int i=1;i<=n;i++) i==n?printf("%d ",ask(i)):printf("%d ",ask(i)); }return 0; }
有一种悲伤叫做HDU的Presentation Error
提交了好几次,都出现这个东西,惊呆了,看了看题解,有个微小的细节:当最后一个输出时要严格输出" ",而不能先输出空格,再输出“ ”
HDU上刷的题太少了。。。