ZOJ 3299-Fall the Brick(线段树+离散化)

题意:

n个区间 ,给出区间的左右坐标 ,区间内填满宽度为1的箱子,有m个板子给出板子的高度和左右坐标(同高度不重叠)

所有箱子从上向下落,求每块板子能接到的箱子数。

分析:

首先给的区间很大,一开始直接存ME了,所以要先把给定的区间离散化 箱子的宽度是1则使维护区间左闭右开,才能得正确的数量。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<1|1
#define All 1,N,1
#define N 100010
#define read freopen("in.txt", "r", stdin)
const ll  INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod =  1000000007;
int res[4*N],f[1<<20],x,y;
ll sum[1<<20],tmp[N],add[1<<20];
struct brick{
    int l,r,lid,rid;
}a[N];
struct board{
    int l,r,lid,rid,h,id;
}b[N];
bool cmp(board u,board v){
    return u.h>v.h;
}
void pushup(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void pushdown(int rt,int l,int r){
    int mid=(l+r)>>1;
    if(add[rt]){
       add[rt<<1]+=add[rt];
       add[rt<<1|1]+=add[rt];
       sum[rt<<1]+=1LL*(res[mid+1]-res[l])*add[rt];
       sum[rt<<1|1]+=1LL*(res[r+1]-res[mid+1])*add[rt];
       add[rt]=0;
    }
}
void build(int l,int r,int rt){
    sum[rt]=add[rt]=f[rt]=0;
    if(l==r)return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void update_add(int L,int R,int v,int l,int r,int rt){
    if(L<=l&&R>=r){
       add[rt]+=v;
        sum[rt]+=(res[r+1]-res[l])*v;
        return;
    }
    pushdown(rt,l,r);
    int m=(l+r)>>1;
    if(L<=m)update_add(L,R,v,lson);
    if(R>m)update_add(L,R,v,rson);
    pushup(rt);
}
void update_cle(int L,int R,int l,int r,int rt){
    if(f[rt])return;
    if(L<=l&&R>=r){
        sum[rt]=0;
        f[rt]=1;
        return;
    }
    pushdown(rt,l,r);
    int m=(l+r)>>1;
    if(L<=m)update_cle(L,R,lson);
    if(R>m)update_cle(L,R,rson);
    pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){
        if(f[rt])return 0;
        if(L<=l&&R>=r){
            return sum[rt];
        }
        pushdown(rt,l,r);
        ll num=0;
       int  m=(l+r)>>1;
        if(L<=m)num+=query(L,R,lson);
        if(R>m)num+=query(L,R,rson);
        return num;
}
int main()
{
    while(~scanf("%d%d",&x,&y)){
            int len=0;
        for(int i=0;i<x;++i){
            scanf("%d%d",&a[i].l,&a[i].r);
            res[len++]=a[i].l;
            res[len++]=a[i].r;
        }
        for(int i=0;i<y;++i){
            scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].h);
            res[len++]=b[i].l;
            res[len++]=b[i].r;
            b[i].id=i;
        }
        //离散化
        sort(res,res+len);
        len=unique(res,res+len)-res;
        for(int i=0;i<x;++i){
            a[i].lid=lower_bound(res,res+len,a[i].l)-res;
            a[i].rid=lower_bound(res,res+len,a[i].r)-res;
        }
        for(int i=0;i<y;++i){
            b[i].lid=lower_bound(res,res+len,b[i].l)-res;
            b[i].rid=lower_bound(res,res+len,b[i].r)-res;
        }
        build(0,len-1,1);
        for(int i=0;i<x;++i)
            update_add(a[i].lid,a[i].rid-1,1,0,len-1,1);//左开右闭
             sort(b,b+y,cmp);
            for(int i=0;i<y;++i){
                tmp[b[i].id]=query(b[i].lid,b[i].rid-1,0,len-1,1);
                update_cle(b[i].lid,b[i].rid-1,0,len-1,1);
            }
        for(int i=0;i<y;++i){
            printf("%I64d\n",tmp[i]);
        }
        printf("\n");
    }
return 0;
}    
时间: 2024-11-08 20:23:15

ZOJ 3299-Fall the Brick(线段树+离散化)的相关文章

POJ_2528 Mayor&#39;s poster(线段树+离散化)

题目请点我 题解: 这道题与之前的题目相比重点在于一个映射的预处理,题目所给的区间达到10000000,而最多只有10000个点,如果直接建树的话太过于空旷.把这些区间的左右节点一一对应,最多有4×10000个点,远小于之前的10000000,而且区间之间的对应关系也不会改变. 举个例子: 区间:[2,6],[4,8],[6,10] 我们进行下面对应: 2 4 6 8 10 1 2 3 4 5 则原区间变为[1,3],[2,4],[3,5].可以发现它们之间的覆盖关系并没有改变,但是却紧凑了很多

POJ - 2528 - Mayor&#39;s posters 【线段树+离散化+补点】

http://poj.org/problem?id=2528 #include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; in

HDU5124:lines(线段树+离散化)或(离散化思想)

http://acm.hdu.edu.cn/showproblem.php?pid=5124 Problem Description John has several lines. The lines are covered on the X axis. Let A is a point which is covered by the most lines. John wants to know how many lines cover A. Input The first line conta

hdu1828 Picture(线段树+离散化+扫描线)两种方法

C - Picture Time Limit:2000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wall. Their sides are all vertical or

Poj 2528 Mayor&#39;s posters (线段树+离散化)

题目连接: http://poj.org/problem?id=2528 题目大意: 有10000000块瓷砖,n张海报需要贴在墙上,每张海报所占的宽度和瓷砖宽度一样,长度是瓷砖长度的整数倍,问按照所给海报顺序向瓷砖上贴海报,最后有几张海报是可见的? 解题思路: 因为瓷砖块数和海报张数多,首选线段树,如果按照常规的建树方式,把瓷砖当做数的节点,肯定会MTL......... 所以我们可以用海报的起点和终点当做树的节点,这样树的节点才有20000个,但是这样建树的话,求海报覆盖了那些节点会很复杂,

hdu 5124 lines (线段树+离散化)

lines Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 620    Accepted Submission(s): 288 Problem Description John has several lines. The lines are covered on the X axis. Let A is a point which

poj2528 线段树+离散化

1 //Accepted 1960K 110MS 2 //线段树+离散化 3 //把所有的坐标排序,从小到大编号,建立线段树 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 using namespace std; 11 /** 1

POJ 2528 (线段树+离散化) Mayor&#39;s posters

因为将每个单位都作为一个最小单元的话会爆内存的 所以,将海报的每个端点进行排序,将这些端点最为最小的区间. 毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了. 萌萌的AC代码君贴上. 1 //#define LOCAL 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 7 int n; 8 struct CPost 9

poj2528--Mayor&#39;s posters(线段树+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41785   Accepted: 12164 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

ZOJ 3772 Calculate the Function 线段树+矩阵

Calculate the FunctionTime Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-04-09) Description You are given a list of numbers A1A2 .. AN and M queries. For the i-th query