zoj 3299 Fall the Brick 离散化+区间更新+区间查询

离散化然后套线段树就行。

//author: CHC
//First Edit Time:  2015-07-17 17:46
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
#include <limits>
using namespace std;
typedef long long LL;
const int MAXN=100000+5;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits<LL>::max();
#define lson L,mid,rt<<1
#define rson mid+1,R,rt<<1|1
struct Tree {
    LL cnt;
    int flag;
    int v;
}tr[MAXN<<4];
int id[MAXN*4];
void pushup(int rt){
    tr[rt].cnt=tr[rt<<1].cnt+tr[rt<<1|1].cnt;
}
void pushdownA(int L,int R,int rt);
void pushdownB(int L,int R,int rt);
void pushdownA(int L,int R,int rt){
    if(L==R)return ;
    int mid=(L+R)>>1;
    if(tr[rt].flag&1){
        if(tr[rt<<1].flag&2)pushdownB(lson);
        if(tr[rt<<1|1].flag&2)pushdownB(rson);
        tr[rt<<1].v+=tr[rt].v;
        tr[rt<<1|1].v+=tr[rt].v;
        tr[rt<<1].cnt+=(LL)tr[rt].v*(id[mid+1]-id[L]);
        tr[rt<<1|1].cnt+=(LL)tr[rt].v*(id[R+1]-id[mid+1]);
        tr[rt<<1].flag=tr[rt<<1|1].flag=1;
        tr[rt].flag=0;
        tr[rt].v=0;
    }
    pushdownB(L,R,rt);
}
void pushdownB(int L,int R,int rt){
    if(L==R)return ;
    //int mid=(L+R)>>1;
    if(tr[rt].flag&2){
        tr[rt<<1].v=tr[rt<<1|1].v=0;
        tr[rt<<1].cnt=tr[rt<<1|1].cnt=0;
        tr[rt<<1].flag=tr[rt<<1|1].flag=2;
        tr[rt].flag=0;
        tr[rt].v=tr[rt].cnt=0;
    }
}
void build(int L,int R,int rt){
    tr[rt].v=tr[rt].flag=tr[rt].cnt=0;
    if(L==R)return ;
    int mid=(L+R)>>1;
    build(lson);build(rson);
}
void update(int L,int R,int rt,int l,int r,int v,int flag){
    if(l<=L&&R<=r){
        if(flag==1){
            if(tr[rt].flag&2)pushdownB(L,R,rt);
            tr[rt].v+=v;
            tr[rt].cnt+=(LL)(id[R+1]-id[L])*v;
            tr[rt].flag=1;
        }
        if(flag==2){
            tr[rt].v=0;
            tr[rt].cnt=0;
            tr[rt].flag=2;
        }
        return ;
    }
    pushdownA(L,R,rt);
    int mid=(L+R)>>1;
    if(l<=mid)update(lson,l,r,v,flag);
    if(r>mid)update(rson,l,r,v,flag);
    pushup(rt);
}
LL query(int L,int R,int rt,int l,int r){
    //printf("%d %d %d %d\n",L,R,l,r);
    if(l<=L&&R<=r)return tr[rt].cnt;
    pushdownA(L,R,rt);
    int mid=(L+R)>>1;
    LL ans=0;
    if(l<=mid)ans+=query(lson,l,r);
    if(r>mid)ans+=query(rson,l,r);
    pushup(rt);
    return ans;
}
struct node {
    int l,r,lid,rid;
}a[MAXN];
struct node1 {
    int l,r,lid,rid,h,id;
}b[MAXN];
int cmp(const node1 &x,const node1 &y){
    return x.h>y.h;
}
int n,m;
LL ans[MAXN];
int main()
{
    while(~scanf("%d%d",&n,&m)){
        id[0]=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&a[i].l,&a[i].r);
            id[++id[0]]=a[i].l;
            id[++id[0]]=a[i].r;
            //printf("%d %d\n",a[i].l,a[i].r);
        }
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].h);
            b[i].id=i;
            id[++id[0]]=b[i].l;
            id[++id[0]]=b[i].r;
            //printf("%d %d\n",b[i].l,b[i].r);
        }
        sort(b,b+m,cmp);
        sort(id+1,id+1+id[0]);
        id[0]=unique(id+1,id+1+id[0])-id-1;
        for(int i=0;i<n;i++){
            a[i].lid=lower_bound(id+1,id+1+id[0],a[i].l)-id;
            a[i].rid=lower_bound(id+1,id+1+id[0],a[i].r)-id;
        }
        for(int i=0;i<m;i++){
            b[i].lid=lower_bound(id+1,id+id[0]+1,b[i].l)-id;
            b[i].rid=lower_bound(id+1,id+id[0]+1,b[i].r)-id;
        }
        build(1,id[0],1);
        for(int i=0;i<n;i++){
            update(1,id[0],1,a[i].lid,a[i].rid-1,1,1);
        }
        for(int i=0;i<m;i++){
            ans[b[i].id]=query(1,id[0],1,b[i].lid,b[i].rid-1);
        //printf("here");
            update(1,id[0],1,b[i].lid,b[i].rid-1,0,2);
        }
        //printf("here");
        for(int i=0;i<m;i++){
            printf("%lld\n",ans[i]);
        }
        puts("");
        //printf("%d\n",id[0]);
        //for(int i=1;i<=id[0];i++){
        //printf("%d ",id[i]);
        //}
        //puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值