标签:区间更新 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