ZOJ3299:Fall the Brick(区间更新)

Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just down from the very high Heaven). These days the God lives in a
2D world, so he just throw the bricks in a vertical plane. Each time, the God throws a line of bricks. The width of each brick is 1, and the length will be given.

t__nt is a hero in the world and he is trying his best to save the world. Now he has made m horizontal boards in the air with his magic power to stop the bricks.
If one brick falls onto a board, it can not fall down any more. Notice that, for a line of bricks, consecutive bricks are not connected. So when some bricks touch a board, the others will continues to fall down. Now, t__nt wants to know how
many bricks each board holds after the God‘s crazy action. He asks you, an ACMer, to help him.

Input

There are no more then 10 cases. There is a blank line between consecutive cases. The first line of each case contains two integers nm (0 < nm <=
100000), indicating the number of lines of bricks and number of horizontal boards made by t__nt. n lines follow, each contains two integers liri (0 <= li < ri <= 30000000). li and ri is
the x-coordinates for the left side and the right side of the line of bricks. m lines follow, each contains three integers aibi, and hi (0 <= ai < bi <=
30000000; 0 < hi < 1000000000), which means that board i is at height hi and the extreme points are ai and bi. You may assume no two boards with same height will overlap with each
other.

Output

For each case, print m lines. The ith line means the number of bricks on board i at last. Print a blank line after each case.

Sample Input

1 2
1 8
1 5 8
3 7 6

Sample Output

4
2


题意:有n块板砖从天而降,为了不被砸死,弄了m块木板来挡,每块板砖长度为1单位,给出连续板砖的范围还有木板的范围与高度,问最后每块木板上有几块板砖

思路:由于数字大,首先要离散化,然后位于高处的木板与低处的木板有重合的话,高处先挡下,然后再去计算

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define up(i,x,y) for(i=x;i<=y;i++)
#define down(i,x,y) for(i=x;i>=y;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define w(a) while(a)
#define LL long long
const double pi = acos(-1.0);
#define N 100005
#define mod 19999997
const int INF = 0x3f3f3f3f;
#define exp 1e-8

LL sum[1<<20],col[1<<20],ans[N];
int seg[N*4],len;
bool flag[1<<20];
int n,m;
struct brick
{
    int l,r,lid,rid;
}a[N];
struct board
{
    int l,r,h,lid,rid,id;
}b[N];

int cmp(board a,board b)//高的木板在前
{
    return a.h>b.h;
}

void push_down(int i,int l,int r)
{
    int mid = (l+r)/2;
    if(col[i])
    {
        col[ls] += col[i];
        col[rs] += col[i];
        sum[ls] += (LL)col[i]*(seg[mid+1]-seg[l]);
        sum[rs] += (LL)col[i]*(seg[r+1]-seg[mid+1]);
        col[i] = 0;
    }
}

void build(int i,int l,int r)
{
    sum[i] = col[i] = 0;
    flag[i] = false;
    if(l==r) return;
    int mid = (l+r)/2;
    build(ls,l,mid);
    build(rs,mid+1,r);
}

void updata1(int L,int R,int val,int l,int r,int i)
{
    if(L<=l && r<=R)
    {
        col[i]+=val;
        sum[i]+=val*(seg[r+1]-seg[l]);
        return;
    }
    push_down(i,l,r);
    int mid = (l+r)/2;
    if(L<=mid)
    updata1(L,R,val,l,mid,ls);
    if(R>mid)
    updata1(L,R,val,mid+1,r,rs);
    sum[i] = sum[ls]+sum[rs];
}

void updata2(int L,int R,int l,int r,int i)
{
    if(flag[i]) return;
    if(L<=l && r<=R)
    {
        flag[i] = true;
        sum[i]=0;
        return;
    }
    push_down(i,l,r);
    int mid = (l+r)/2;
    if(L<=mid)
    updata2(L,R,l,mid,ls);
    if(R>mid)
    updata2(L,R,mid+1,r,rs);
    sum[i] = sum[ls]+sum[rs];
}

LL query(int L,int R,int l,int r,int i)
{
    if(flag[i]) return 0;
    if(L<=l && r<=R)
    {
        return sum[i];
    }
    push_down(i,l,r);
    int mid = (l+r)/2;
    LL ret = 0;
    if(L<=mid)
    ret+=query(L,R,l,mid,ls);
    if(R>mid)
    ret+=query(L,R,mid+1,r,rs);
    return ret;
}

int main()
{
    int i,j,k;
    w(~scanf("%d%d",&n,&m))
    {
        len = 0;
        up(i,0,n-1)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            seg[len++] = a[i].l;
            seg[len++] = a[i].r;
        }
        up(i,0,m-1)
        {
            scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].h);
            b[i].id = i;
            seg[len++] = b[i].l;
            seg[len++] = b[i].r;
        }
        //排序,去重,然后离散化
        sort(seg,seg+len);
        len = unique(seg,seg+len)-seg;
        up(i,0,n-1)
        {
            a[i].lid = lower_bound(seg,seg+len,a[i].l)-seg;
            a[i].rid = lower_bound(seg,seg+len,a[i].r)-seg;
        }
        up(i,0,m-1)
        {
            b[i].lid = lower_bound(seg,seg+len,b[i].l)-seg;
            b[i].rid = lower_bound(seg,seg+len,b[i].r)-seg;
        }
        build(1,0,len-1);//建树
        up(i,0,n-1)//对每个区间有几块板砖进行更新
        {
            updata1(a[i].lid,a[i].rid-1,1,0,len-1,1);
        }
        sort(b,b+m,cmp);
        up(i,0,m-1)//查询每块木板上有几块板砖,然后对于已挡住的部分进行清零处理
        {
            ans[b[i].id] = query(b[i].lid,b[i].rid-1,0,len-1,1);
            updata2(b[i].lid,b[i].rid-1,0,len-1,1);
        }
        up(i,0,m-1)
        printf("%lld\n",ans[i]);
        printf("\n");
    }

    return 0;
}

时间: 2024-08-02 20:50:22

ZOJ3299:Fall the Brick(区间更新)的相关文章

zoj3299 Fall the Brick

Time Limit: 3 Seconds      Memory Limit: 32768 KB Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just down from the very high Heaven). These days the God lives in a 2D world, so he

线段树区间更新+离散化——ZOJ 3299

对应ZOJ题目:点击打开链接 Fall the Brick Time Limit: 3000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Submit Status Description Now the God is very angry, so he wants to punish the lazy, greedy humans. He chooses to throw some lines of bricks (just

HDU 1689 Just a Hook 线段树区间更新求和

点击打开链接 Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18894    Accepted Submission(s): 9483 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible

hdu 4970 树状数组区间更新 思维题

http://acm.hdu.edu.cn/showproblem.php?pid=4970 好像还没有用树状数组写过区间更新,但是树状数组的确比线段树快很多,不知道跟ZKW线段树比效率怎么样: 先贴个模板: #include <cstdio> const int MAXN = 1024; int B[MAXN], C[MAXN]; #define LOWBIT(x) ((x)&(-(x))) void bit_update(int *a, int p, int d) { for (

51nod_1199 树的先跟遍历+区间更新树状数组

题目是中文,所以不讲题意 做法顺序如下: 使用先跟遍历,把整棵树平铺到一维平面中 使用自己整的区间更新树状数组模板进行相关操作. http://www.cnblogs.com/rikka/p/7359185.html 放代码如下: 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeL

HDU 1556 Color the ball(线段树:区间更新)

http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和线段树都可以,拿这道题来入门一下线段树的区间更新. 1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int maxn = 1000

hdu 1698(线段树区间更新)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 30080    Accepted Submission(s): 14859 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing

POJ 3468 A Simple Problem with Integers(树状数组区间更新)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97217   Accepted: 30358 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

HDU 1398:Just a Hook(线段树区间更新)

http://acm.hdu.edu.cn/showproblem.php?pid=1698 Just a Hook Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of