3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
1 1 1 3 2 1
一个线段树区间更新问题。。直接写就是了
每次更新为了节省时间只需在需要更新的区间+1就OK了。
#include <stdio.h> #include <string.h> struct node { int left,right,count; }c[100005*3]; int sum[100005]; void build(int l,int r,int root)//这个就不多说了 { c[root].left=l; c[root].right=r; c[root].count=0; if(l==r) return ; int mid=(l+r)/2; build(l,mid,root*2); build(mid+1,r,root*2+1); } void update(int l,int r,int root)//更新 { if(c[root].left==l&&c[root].right==r)//只需要在这个区间+1就行了,节省时间,不用找到每个数 { c[root].count++; return ; } int mid=(c[root].left+c[root].right)/2; if(mid<l) update(l,r,root*2+1); else if(mid>=r) update(l,r,root*2); else { update(l,mid,root*2); update(mid+1,r,root*2+1); } } void tosum(int root)//求和 { for(int i=c[root].left;i<=c[root].right;i++) sum[i]+=c[root].count; if(c[root].left==c[root].right) return ; tosum(root*2); tosum(root*2+1); } int main() { int n; while(scanf("%d",&n)&&n) { memset(sum,0,sizeof(sum)); memset(&c,0,sizeof(&c)); build(1,n,1); for(int i=0;i<n;i++) { int l,r; scanf("%d %d",&l,&r); update(l,r,1); } tosum(1); printf("%d",sum[1]); for(int i=2;i<=n;i++) printf(" %d",sum[i]); printf("\n"); } return 0; }