- 题目大意
给你N个气球,不断刷新指定区间的颜色,刷新N次,最后输出每一个气球的刷新次数。
- 解题思路
利用线段树来做,线段树的每一个节点都代表了一个区间,然后利用一个特殊值来存储这个区间的信息,然后刷新点的信息来找这个区间,找到后+1即可。
- 代码
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cstring> using namespace std; const int maxn=100001; int ans; struct node { int l,r,sum; }t[4*maxn]; void build(int l,int r,int k) { int mid; if(l==r) { t[k].l=l; t[k].r=r; t[k].sum=0; return; } mid=(l+r)/2; t[k].l=l; t[k].r=r; t[k].sum=0; build(l,mid,2*k); build(mid+1,r,2*k+1); } void add(int l,int r,int k) { int mid; if(t[k].r==r&&t[k].l==l) { t[k].sum++; return; } if(t[k].l==t[k].r) return; mid=(t[k].r+t[k].l)/2; if(r<=mid) add(l,r,2*k); else if(l>mid) add(l,r,2*k+1); else { add(l,mid,2*k); add(mid+1,r,2*k+1); } } int findd(int l,int r,int k) { int mid; if(t[k].l==l&&t[k].r==r) { return t[k].sum; } if(t[k].l==t[k].r) return 0; mid=(t[k].r+t[k].l)/2; if(r<=mid) return t[k].sum+findd(l,r,2*k); else if(l>mid) return t[k].sum+findd(l,r,2*k+1); else { return t[k].sum+findd(l,mid,2*k)+findd(mid+1,r,2*k+1); } } int main() { int n,a,b; while(scanf("%d",&n)) { if(n==0) break; build(1,n,1); for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); add(a,b,1); } for(int j=1;j<n;j++) { ans=findd(j,j,1); printf("%d ",ans); } printf("%d\n",findd(n,n,1)); } return 0; }