zoukankan      html  css  js  c++  java
  • 线段树(成段更新,区间求和lazy操作 )

    hdu1556

    Color the ball

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9143    Accepted Submission(s): 4677
    Problem 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

    <pre name="code" class="cpp">#include"stdio.h"
    #include"string.h"
    #include"iostream"
    #include"map"
    #include"string"
    #include"queue"
    #include"stdlib.h"
    #include"math.h"
    #define M 100009
    #define eps 1e-8
    #define inf 1000000000
    #define mod 1000000000
    #define INF 1000000000
    using namespace std;
    struct st
    {
        int l,r,sum,add,mark;
    }a[M*4];
    int ans;
    void make(int l,int r,int k)
    {
        a[k].l=l;
        a[k].r=r;
        a[k].mark=0;
        a[k].add=0;
        if(l==r)
        {
            a[k].sum=0;
            return ;
        }
        int mid=(l+r)/2;
        make(l,mid,k*2);
        make(mid+1,r,k*2+1);
        a[k].sum=a[k*2].sum+a[k*2+1].sum;
    }
    void updata(int l,int r,int p,int k)
    {
        if(a[k].l==l&&a[k].r==r)
        {
            a[k].sum+=(r-l+1);
            a[k].add+=p;//当多次刚好更新还区间的时候,只更新到该区间,所以要连加
            a[k].mark=1;
            return;
        }
        if(a[k].mark)
        {
            a[k*2].sum+=(a[k*2].r-a[k*2].l+1)*a[k].add;
            a[k*2].add+=a[k].add;
            a[k*2].mark=1;
            a[k*2+1].sum+=(a[k*2+1].r-a[k*2+1].l+1)*a[k].add;
            a[k*2+1].add+=a[k].add;
            a[k*2+1].mark=1;
            a[k].mark=0;
            a[k].add=0;//当向下延伸的时候,需要把当前区间赋为0,
        }
        int mid=(a[k].l+a[k].r)/2;
        if(r<=mid)
            updata(l,r,p,k*2);
        else if(l>mid)
            updata(l,r,p,k*2+1);
        else
        {
            updata(l,mid,p,k*2);
            updata(mid+1,r,p,k*2+1);
        }
        a[k].sum=a[k*2].sum+a[k*2+1].sum;
    }
    void query(int p,int k)
    {
        if(a[k].l==p&&a[k].r==p)
        {
            ans+=a[k].sum;
            return;
        }
        if(a[k].mark)
        {
            a[k*2].sum+=(a[k*2].r-a[k*2].l+1)*a[k].add;
            a[k*2].add+=a[k].add;
            a[k*2].mark=1;
            a[k*2+1].sum+=(a[k*2+1].r-a[k*2+1].l+1)*a[k].add;
            a[k*2+1].add+=a[k].add;
            a[k*2+1].mark=1;
            a[k].mark=0;
            a[k].add=0;
        }
        int mid=(a[k].l+a[k].r)/2;
        if(p<=mid)
            query(p,k*2);
        else
            query(p,k*2+1);
        a[k].sum=a[k*2].sum+a[k*2+1].sum;
    }
    int main()
    {
        int n,i;
        while(scanf("%d",&n),n)
        {
            make(1,n,1);
            int x,y;
            for(i=1;i<=n;i++)
            {
                scanf("%d%d",&x,&y);
                updata(x,y,1,1);
            }
            for(i=1;i<=n;i++)
            {
                ans=0;
                query(i,1);
                if(i==1)
                printf("%d",ans);
                else
                printf(" %d",ans);
            }
            printf("
    ");
        }
        return 0;
    }
    


    
    

  • 相关阅读:
    switch多分枝语句
    自动扫描判断数组奇偶 直接在控制台输入
    if else语句
    1231作业
    字符集和字符编码
    12.28作业
    置顶广告
    图片库
    js实现隔行换色及其鼠标滑过变色
    【转载】display:inline-block兼容ie6/7的写法
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348194.html
Copyright © 2011-2022 走看看