题意:
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
思路:
这个题目可以用线段树来做,可以用线段树的段更新点询问,每次把a,b全部+1,最后全部查询一遍就行了,水题不解释,不理解直接看代码。
#include<stdio.h> #include<string.h> #define lson l ,mid ,t << 1 #define rson mid + 1 ,r ,t << 1 | 1 __int64 sum[440000] ,mark[440000]; void Pushup(int t) { sum[t] = sum[t<<1] + sum[t<<1|1]; } void Pushdown(int t ,int ll) { if(mark[t]) { mark[t<<1] += mark[t]; mark[t<<1|1] += mark[t]; sum[t<<1] += (ll - (ll >> 1)) * mark[t]; sum[t<<1|1] += (ll >> 1) * mark[t]; mark[t] = 0; } } void BuidTree() { memset(sum ,0 ,sizeof(sum)); memset(mark ,0 ,sizeof(mark)); } void Update(int l ,int r ,int t ,int a ,int b ,int c) { if(a <= l && b >= r) { sum[t] += (r - l + 1) * c; mark[t] += c; return; } Pushdown(t ,r - l + 1); int mid = (l + r) >> 1; if(a <= mid) Update(lson ,a ,b ,c); if(b > mid) Update(rson ,a ,b ,c); Pushup(t); } __int64 Query(int l ,int r ,int t ,int a ,int b) { if(a <= l && b >= r) return sum[t]; Pushdown(t ,r - l + 1); int mid = (l + r) >> 1; __int64 ans = 0; if(a <= mid) ans = Query(lson ,a ,b); if(b > mid) ans += Query(rson ,a ,b); return ans; } int main () { int n ,a ,b ,i; while(~scanf("%d" ,&n) && n) { BuidTree(); for(i = 1 ;i <= n ;i ++) { scanf("%d %d" ,&a ,&b); Update(1 ,n ,1 ,a ,b ,1); } for(i = 1 ;i <= n ;i ++) if(i == n) printf("%I64d " ,Query(1 ,n ,1 ,i ,i)); else printf("%I64d " ,Query(1 ,n ,1 ,i ,i)); } return 0; }