Color the ball (线段树的区间更新问题)
Posted moomcake
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Color the ball (线段树的区间更新问题)相关的知识,希望对你有一定的参考价值。
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
3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
Sample Output
1 1 1 3 2 1
题意:长度为n的区间,n次更新,每一次都将该区间的气球的颜色染一次色,问最终每一个气球染了几次色。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN=2e5+10; 8 typedef long long ll; 9 #define lson l,m,i<<1 10 #define rson m+1,r,i<<1|1 11 typedef struct Node 12 { 13 ll l,r; 14 ll mid() 15 { 16 return (l+r)/2.0; 17 } 18 ll value; 19 } Node; 20 Node node[MAXN<<2]; 21 ll sum[MAXN<<2]; 22 ll add[MAXN<<2]; 23 void push_up(ll i) 24 { 25 sum[i]=sum[i<<1]+sum[i<<1|1]; 26 } 27 void Build(ll l,ll r,ll i) 28 { 29 node[i].l=l; 30 node[i].r=r; 31 node[i].value=0; 32 sum[i]=0; 33 add[i]=0; 34 if(l==r) 35 { 36 sum[i]=0; 37 node[i].value=0; 38 return ; 39 } 40 ll m=node[i].mid(); 41 Build(lson); 42 Build(rson); 43 push_up(i); 44 } 45 ll M; 46 void Push_down(ll i,ll len) 47 { 48 if(add[i]) 49 { 50 add[i<<1]+=add[i]; 51 add[i<<1|1]+=add[i]; 52 sum[i<<1]+=add[i]*(len-(len>>1)); 53 sum[i<<1|1]+=add[i]*(len>>1); 54 add[i]=0; 55 } 56 } 57 void query(ll l,ll r,ll i) 58 { 59 if(node[i].l==l&&node[i].r==r) 60 { 61 M+=sum[i]; 62 return; 63 } 64 ll m=node[i].mid(); 65 Push_down(i,node[i].r-node[i].l+1); 66 if(r<=m) 67 query(l,r,i<<1); 68 else 69 { 70 if(l>m) 71 query(l,r,i<<1|1); 72 else 73 { 74 query(lson); 75 query(rson); 76 } 77 } 78 } 79 void update(ll l,ll r,ll i,ll v) 80 { 81 82 if(node[i].r==r&&node[i].l==l) 83 { 84 add[i]+=v; 85 sum[i]+=v*(r-l+1); 86 return; 87 } 88 ll m=node[i].mid(); 89 Push_down(i,node[i].r-node[i].l+1); 90 if(r<=m) 91 update(l,r,i<<1,v); 92 else 93 { 94 if(l>m) 95 update(l,r,i<<1|1,v); 96 97 else 98 { 99 update(l,m,i<<1,v); 100 update(m+1,r,i<<1|1,v); 101 } 102 } 103 push_up(i); 104 } 105 int main() 106 { 107 ll m,n,a,b,T,c; 108 ll flag=0; 109 while(scanf("%lld",&m)!=-1&&m) 110 { 111 ll k=m; 112 Build(1,m,1); 113 while(k--) 114 { 115 scanf("%lld%lld",&a,&b); 116 update(a,b,1,1); 117 } 118 for(ll i=1;i<=m;i++) 119 { 120 M=0; 121 query(i,i,1); 122 printf("%lld%c",M,i==m?‘ ‘:‘ ‘); 123 } 124 } 125 return 0; 126 }
题解:线段树的区间更新问题,上篇博客每行代码有详细解释。