Color the ball

来源:互联网 发布:备案域名转让 编辑:程序博客网 时间:2024/06/05 23:01

区间更新+点查询

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,输入结束。
Output
每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
Sample Input
31 12 23 331 11 21 30
Sample Output
1 1 13 2 1

#include<stdio.h>#include<string.h>#include<algorithm>#define maxn 100005using namespace std;struct list{int left;int right;int sum;int weight;}tree[maxn*4];void build(int i,int left,int right);void update(int i,int ql,int qr,int data,int left,int right);void query(int i,int pos,int left,int right);void pushup(int i);void pushdown(int i,int left,int right);int ans;int main(){int n;while(scanf("%d",&n),n){memset(tree,0,sizeof(tree));build(1,1,n);for(int i=0;i<n;i++){int a,b;scanf("%d%d",&a,&b);update(1,a,b,1,1,n);}for(int i=1;i<=n;i++){ans=0;query(1,i,1,n);printf("%d",ans);if(i==n)putchar('\n');elseputchar(' ');}}return 0;}void build(int i,int left,int right){tree[i].left=left;tree[i].right=right;tree[i].sum=0;tree[i].weight=0;if(left==right){tree[i].sum=0;return ;}int mid=(left+right)>>1;build(i<<1,left,mid);build(i<<1|1,mid+1,right);pushup(i);}void update(int i,int ql,int qr,int data,int left,int right){if(ql<=left&&qr>=right){tree[i].weight+=data;tree[i].sum+=data*(right-left+1);return ;}pushdown(i,left,right);int mid=(left+right)>>1;if(ql<=mid)update(i<<1,ql,qr,data,left,mid);if(qr>=mid+1)update(i<<1|1,ql,qr,data,mid+1,right);pushup(i);}void query(int i,int pos,int left,int right){if(pos==left&&pos==right){ans=tree[i].sum;return ;}pushdown(i,left,right);int mid=(left+right)>>1;if(pos<=mid)query(i<<1,pos,left,mid);elsequery(i<<1|1,pos,mid+1,right);}void pushup(int i){tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;}void pushdown(int i,int left,int right){if(tree[i].weight){tree[i<<1].weight+=tree[i].weight;tree[i<<1|1].weight+=tree[i].weight;int mid=(left+right)>>1;tree[i<<1].sum+=tree[i].weight*(mid-left+1);tree[i<<1|1].sum+=tree[i].weight*(right-mid);tree[i].weight=0;}}


#include<stdio.h>#include<string.h>#define maxn 100005struct list{int left,right,tag;}tree[maxn*4];void pushdown(int i){if(tree[i].tag){tree[i<<1].tag+=tree[i].tag;tree[i<<1|1].tag+=tree[i].tag;tree[i].tag=0;}}void update(int i,int ql,int qr,int left,int right){if(ql<=left&&qr>=right){tree[i].tag++;return ;}pushdown(i);int mid=(left+right)>>1;if(ql<=mid)update(i<<1,ql,qr,left,mid);if(qr>mid)update(i<<1|1,ql,qr,mid+1,right);}int query(int i,int pos,int left,int right){if(left==right){return tree[i].tag;}pushdown(i);int mid=(left+right)>>1;if(pos<=mid)return query(i<<1,pos,left,mid);elsereturn query(i<<1|1,pos,mid+1,right);}int main(){int n;while(scanf("%d",&n),n){memset(tree,0,sizeof(tree));for(int i=0;i<n;i++){int a,b;scanf("%d%d",&a,&b);update(1,a,b,1,n);}for(int i=1;i<=n;i++){printf("%d",query(1,i,1,n));if(i==n)putchar('\n');elseputchar(' ');}} return 0;}