zoukankan      html  css  js  c++  java
  • hdu 1556 涂气球 线段树(区间更新~对区间[x,y]更新,求任意节点被更新的次数)

    Color the ball

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 29526    Accepted Submission(s): 14356


    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
     
    //注意laz[]要和线段树数组开一样大小
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<math.h>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    const int  n = 100050;
    using namespace std;
    void pushdown(int num);
    int tre[n * 4];
    int laz[n*4];
    void update(int num, int le, int ri, int x, int y,int z)
    {
        if (x <= le && y >= ri)
        {
            tre[num] = tre[num] + z;//初值为0,z=1
            laz[num] = laz[num] + z;
            return;
        }
        pushdown(num);
        int mid = (le + ri) / 2;
        if (x <= mid)
            update(num * 2, le, mid, x, y, z);
        if (y > mid)
            update(num * 2 + 1, mid + 1, ri, x, y, z);
    }
    void pushdown(int num)
    {
        if (laz[num] != 0)
        {
            tre[num * 2] += laz[num];
            tre[num * 2 + 1] += laz[num];
            laz[num * 2] += laz[num];
            laz[num * 2 + 1] += laz[num];
            laz[num] = 0;
        }
    }
    int query(int num, int le, int ri, int x)
    {
        if (le == ri)
        {
            return tre[num];
        }
        pushdown(num);
        int mid = (le + ri) / 2;
        if (x <= mid)
            return query(num * 2, le, mid, x);
        else
            return query(num * 2 + 1, mid + 1, ri, x);
    }
    int main()
    {
        int t;
        while (cin >> t)
        {
            memset(tre, 0, sizeof(tre));
            memset(laz, 0, sizeof(laz));//初始化延迟标记
            for (int i = 0; i < t; i++)
            {
                int x, y;
                cin >> x >> y;
                update(1, 1, t, x, y, 1);
                cout << query(1, 1, n, x) << endl;
            }
        }
        return 0;
    }

    用结构体储存数据

    #include <stdio.h>
    #include<iostream>
    #include <string.h>
    using namespace std;
    struct node
    {
        int left, right, count;
    }c[100005 * 3];
    int sum[100005];
    void build(int le, int ri, int root)
    {
        c[root].left = le;
        c[root].right = ri;
        c[root].count = 0;
        if (le == ri)
            return;
        int mid = (le + ri) / 2;
        build(le, mid, root * 2);
        build(mid + 1, ri, root * 2 + 1);
    }
    void update(int le, int ri, int root)//更新
    {
        if (c[root].left == le && c[root].right == ri)//只需要在这个区间+1就行了,节省时间,不用找到每个数
        {
            c[root].count++;
            return;
        }
        int mid = (c[root].left + c[root].right) / 2;
        if (mid<le)//如果更新区间在右子树上,就只更新右区间
            update(le, ri, root * 2 + 1);
        else if (mid >= ri)//更新左子树
            update(le, ri, root * 2);
        else//更新区间即在右子树上,又在左子树上
        {
            update(le, mid, root * 2);
            update(mid + 1, ri, root * 2 + 1);
        }
    }
    void tosum(int root)//求和、记录每个气球被涂过的次数
    {
        for (int i = c[root].left; i <= c[root].right; i++)
            sum[i] += c[root].count;
        if (c[root].left == c[root].right)
            return;
        tosum(root * 2);//通过子节点来更新父节点
        tosum(root * 2 + 1);
    }
    int main()
    {
        int n;
        while (scanf("%d", &n) && n)
        {
            memset(sum, 0, sizeof(sum));
            memset(&c, 0, sizeof(&c));
            build(1, n, 1);
            for (int i = 0; i<n; i++)
            {
                int le, ri;
                scanf("%d %d", &le, &ri);
                update(le, ri, 1);
            }
            tosum(1);
            printf("%d", sum[1]);
            for (int i = 2; i <= n; i++)
                printf(" %d", sum[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    关于SubSonic3.0查询或更新时出现System.NullReferenceException异常的处理
    SubSonic3.0使用例子
    Hive:ORC File Format存储格式详解
    HiveQL之Sort by、Distribute by、Cluster by、Order By详解
    Hive之import和export使用详解
    手动安装cloudera manager 5.x(tar包方式)详解
    初次安装hive-2.1.0启动报错问题解决方法
    LAMP下安装zabbix流水
    ESXI虚拟机磁盘管理(精简-厚置-精简)
    VMware esxi 5.5装机方案
  • 原文地址:https://www.cnblogs.com/-citywall123/p/10046252.html
Copyright © 2011-2022 走看看