Color the ballCrawling in process...
Crawling failed Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
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#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int maxn = 100005; struct Tree { int L,R; int val; int Mid() { return (L+R)/2; } }; Tree tree[4*maxn]; //4倍空间一定可以存下 int str[maxn]; //查询时用于计算每个数字出现的次数void BuildTree(int root,int L,int R) //建立线段树 { tree[root].L = L; tree[root].R = R; tree[root].val = 0; if(L != R) { BuildTree(2*root+1,L,tree[root].Mid()); BuildTree(2*root+2,tree[root].Mid()+1,R); } return ; }void Insert(int L,int R,int root) { if(tree[root].L >= L && tree[root].R <= R) //当该区间位于多给的区间中间的时候,val的值需要加1. { tree[root].val++; return ; } if(tree[root].L == tree[root].R) return ; if(tree[root].Mid() >= R) Insert(L,R,root*2+1); //左子树上进行搜索 else if(tree[root].Mid() < L) Insert(L,R,root*2+2);//右子树上进行搜索 else { Insert(L,tree[root].Mid(),root*2+1); Insert(tree[root].Mid()+1,R,root*2+2); } }void Query(int root,int L,int R) //通过判断val的值来看线段树上的某一段是否被记录过 { if(tree[root].val > 0) { for(int i = tree[root].L ; i <= tree[root].R ; i++) str[i] += tree[root].val; } if(tree[root].L == tree[root].R) return ; Query(2*root+1 , L , (L+R)/2); Query(2*root+2 , (L+R)/2+1 , R); }int main() { int N,a,b; while(scanf("%d",&N) != EOF && N) { BuildTree(0,1,N); memset(str,0,sizeof(str)); int x = N; while(x--) { scanf("%d%d",&a,&b); Insert(a,b,0); } Query(0,1,N); for(int i = 1 ; i <= N; i++) { if(i != N) printf("%d ",str[i]); else printf("%d",str[i]); } putchar('\n'); } return 0; }