码迷,mamicode.com
首页 > 其他好文 > 详细

Gym - 101982F Rectangles (扫描线+线段树)

时间:2019-04-27 19:30:15      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:区间更新   date   names   nbsp   ret   代码   pushd   upd   com   

链接:http://codeforces.com/gym/101982/attachments

思路:

问被覆盖次数为奇数次的矩阵的面积并

扫描线求矩阵面积并我们是上界赋为-1,下界赋为1,因为要求覆盖次数为奇数次的,我们直接上下界都赋值为1,然后每次区间更新的时候对这段区间取异或就好了

 

实现代码;

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid ll m = (l + r) >> 1
const ll M = 2e5+10;
struct seg{
    ll l,r,h;
    ll s;
    seg(){}
    seg(ll a,ll b,ll c,ll d):l(a),r(b),h(c),s(d){}
    bool operator < (const seg &cmp) const {
        return h < cmp.h;
    }
}t[M];
ll sum[M<<2],x[M<<2];
ll cnt[M<<2];
void pushup(ll rt){
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void pushdown(ll l,ll r,ll rt){
    if(cnt[rt]){
        mid;
        sum[rt<<1] = x[m] - x[l-1] - sum[rt<<1];
        sum[rt<<1|1] = x[r] - x[m] - sum[rt<<1|1];
        cnt[rt<<1] ^= 1;
        cnt[rt<<1|1] ^= 1;
        cnt[rt] = 0;
    }
}

void update(ll L,ll R,ll c,ll l,ll r,ll rt){
    if(L <= l&&R >= r){
        cnt[rt] ^= 1;
        sum[rt] = (x[r]-x[l-1]) - sum[rt];
        return ;
    }
    pushdown(l,r,rt);
    mid;
    if(L <= m) update(L,R,c,lson);
    if(R > m) update(L,R,c,rson);
    pushup(rt);
}

ll bin(ll key,ll n,ll x[]){
    ll l = 0;ll r = n-1;
    while(l <= r){
        mid;
        if(x[m] == key) return m;
        else if(x[m] < key) l = m+1;
        else r = m-1;
    }
    return -1;
}
int main()
{
    ll n,cas = 1;
    ll a,b,c,d;
    cin>>n;
        ll m = 0;
        while(n--){
            cin>>a>>b>>c>>d;
            x[m] = a;
            t[m++] = seg(a,c,b,1);
            x[m] = c;
            t[m++] = seg(a,c,d,1);
        }
        sort(x,x+m);
        sort(t,t+m);
        ll nn = 1;
        for(ll i = 1;i < m;i++){
            if(x[i]!=x[i-1]) x[nn++] = x[i];
        }
        ll ret = 0;
        for(ll i = 0;i < m-1;i ++){
            ll l = bin(t[i].l,nn,x);
            ll r = bin(t[i].r,nn,x);
            if(l <= r) update(l+1,r,t[i].s,0,M,1);
            ret += sum[1] * (t[i+1].h - t[i].h);
        }
        cout<<ret<<endl;
     return 0;
}

 

Gym - 101982F Rectangles (扫描线+线段树)

标签:区间更新   date   names   nbsp   ret   代码   pushd   upd   com   

原文地址:https://www.cnblogs.com/kls123/p/10779818.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!