• [ACM_数据结构] Color the ball [线段树水题][数组开大]


    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,输入结束。
     

    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
     
     1 #include<cmath>
     2 #include<cstdio>
     3 #define maxn  300000
     4 class Node{
     5 public:
     6     int l,r;
     7     __int64 add;//附加值
     8     __int64 sum;
     9 }node[maxn];
    10 int getRight(int n){//获得满足2^x>=n的最小x[从0层开始,给编号获得层数]
    11     return ceil(log10(n*1.0)/log10(2.0));
    12 }
    13 void build(int l,int r,int num){//输入区间[1,2^getRight(n)],num=1建树
    14     if(l==r){
    15         node[num].l=node[num].r=l;node[num].add=0;node[num].sum=0;
    16         return;
    17     }
    18     node[num].l=l;node[num].r=r;node[num].add=0;node[num].sum=0;
    19     build(l,(l+r)/2,num*2);
    20     build((l+r)/2+1,r,num*2+1);
    21 }
    22 void add(int o,int l,int r,__int64 v){//从o节点开始递归[只要调用时o=1即可]在区间[l,r]全部加v
    23     if(l<=node[o].l && r>=node[o].r){//全覆盖[递归边界]
    24         node[o].add+=v;
    25     }else{
    26         int M=node[o].l+(node[o].r-node[o].l)/2;
    27         if(r<=M)add(o*2,l,r,v);
    28         else if(l>M)add(o*2+1,l,r,v);
    29         else{
    30             add(o*2,l,M,v);
    31             add(o*2+1,M+1,r,v);
    32         }
    33     }
    34     //维护节点o
    35     if(node[o].l!=node[o].r){//如果区间只是一个元素就不算
    36         node[o].sum=node[2*o].sum+node[2*o+1].sum;
    37     }else node[o].sum=0;
    38     node[o].sum+=node[o].add*(node[o].r-node[o].l+1);
    39 }
    40 
    41 //这里addadd是从上往下这条路的累计addadd值[一同回溯记录这条路节点所有add之和,减少了一次回溯累加add值]
    42 //初始时直接令其为0
    43 __int64 sum=0;
    44 void ask(int o,int l,int r,__int64 addadd){//从o节点开始递归[只要调用时o=1即可]在区间[l,r]的和
    45     if(l<=node[o].l && r>=node[o].r){//全覆盖[递归边界]
    46         sum+=(node[o].sum+addadd*(node[o].r-node[o].l+1));
    47     }else{
    48         int M=node[o].l+(node[o].r-node[o].l)/2;
    49         if(r<=M)ask(o*2,l,r,node[o].add+addadd);
    50         else if(l>M)ask(o*2+1,l,r,node[o].add+addadd);
    51         else{
    52             ask(o*2,l,M,node[o].add+addadd);
    53             ask(o*2+1,M+1,r,node[o].add+addadd);
    54         }
    55     }
    56 }
    57 int main(){
    58     int N;
    59     int i,j;
    60     while(scanf("%d",&N) && N){
    61         build(1,1<<getRight(N),1);
    62         for(int k=0;k<N;k++){
    63             scanf("%d%d",&i,&j);
    64             add(1,i,j,1);
    65         }
    66         sum=0;
    67         ask(1,1,1,0);
    68         printf("%lld",sum);
    69         for(i=2;i<=N;i++){
    70             sum=0;
    71             ask(1,i,i,0);
    72             printf(" %lld",sum);
    73         }
    74         printf("
    ");
    75     }return 0;
    76 }
  • 相关阅读:
    【洛谷3778】[APIO2017] 商旅(分数规划+Floyd)
    【AT4114】[ARC095D] Permutation Tree(简单题)
    【AT4352】[ARC101C] Ribbons on Tree(容斥+DP)
    【AT4169】[ARC100D] Colorful Sequences(DP)
    【洛谷4581】[BJOI2014] 想法(随机算法)
    【洛谷5659】[CSP-S2019] 树上的数(思维)
    【AT4439】[AGC028E] High Elements(线段树)
    【CF590E】Birthday(AC自动机+二分图匹配)
    【洛谷4298】[CTSC2008] 祭祀(Dilworth定理+二分图匹配)
    【洛谷3774】[CTSC2017] 最长上升子序列(杨表)
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/3700349.html
Copyright © 2020-2023  润新知