http://acm.hdu.edu.cn/showproblem.php?pid=1556
感觉对线段树还不是很熟练,通过此题学到这种结构体设置方法(线段树的关键就是在结构体的设置),如果对区间内所有元素做同样操作,只需对线段树上对应区间操作即可。否则如果对所有元素操作,会超时,但进行query()要计算到叶子节点。
#include<iostream> #include<cstdio> #include<cstring> #define N 100000 using namespace std; struct node { int l,r; int count; int mid() { return (l+r)>>1; } }; node tree[N*3]; void buildtree(int l,int r,int pos) { tree[pos].l=l; tree[pos].r=r; tree[pos].count=0; if(l==r) return ; buildtree(l,tree[pos].mid(),pos<<1); buildtree(tree[pos].mid()+1,r,(pos<<1)+1); } void update(int l,int r,int pos) { if(tree[pos].l==l&&tree[pos].r==r) { tree[pos].count++; return ; } if(r<=tree[pos].mid()) { update(l,r,pos<<1); } else if(l>tree[pos].mid()) { update(l,r,(pos<<1)+1); } else { update(l,tree[pos].mid(),pos<<1); update(tree[pos].mid()+1,r,(pos<<1)+1); } } void query(int pos,int sum) { if(tree[pos].l==tree[pos].r) { if(tree[pos].l==1) printf("%d",tree[pos].count+sum); else printf(" %d",tree[pos].count+sum); return ; } query(pos<<1,tree[pos].count+sum); query((pos<<1)+1,tree[pos].count+sum); } int main() { int n; while(scanf("%d",&n),n) { int i,t1,t2; memset(tree,0,sizeof(tree)); buildtree(1,n,1); for(i=0;i<n;i++) { scanf("%d%d",&t1,&t2); update(t1,t2,1); } query(1,0); printf("\n"); } }