The 11th Blue Bridge Cup National Championship C\C++A Group Parity Coverage

Insert picture description here
This question is a template question for scanning lines, but you need to change the information stored in the line segment tree. Each node needs to store how much length under the current node is covered by odd (or even) rectangles.
And the coordinate range of this question is very large, but the number is very small, so you can do it after discretization.
There should be no problems with this code. If someone finds a problem, please chat with me in time to change it~

#include <bits/stdc++.h>
#define IO (ios::sync_with_stdio(false), cin.tie(0), cout.tie(0))
#define INF 0x3f3f3f3f
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vs vector<int>
#define pk push_back
#define vss vector<vector<int> >
#define sz(x) (int)(x).size()
#define mk(a, b) make_pair(a, b)
#define Max(a, b) (a > b ? a : b)
#define Min(a, b) (a < b ? a : b)
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define rep(a, b, c) for(register int a = b; a <= c; ++ a)
#define per(a, b, c) for(register int a = b; a >= c; -- a)
using namespace std;

const int N = 1e5 + 5;

int n, m, T;
int alls[N << 2];

struct Segment
{
    
    
	int x, y1, y2;
	int k;
	bool operator< (const Segment &q) const {
    
    
		return x < q.x;
	}
} seg[N << 2];

struct Node 
{
    
    
	int l, r;
	int cnt;
	int len1, len2;
}tr[N << 4];

template<class T>
inline void read(T &x)
{
    
    
	x = 0; T f = 1; char c = getchar();
	while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
	while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	x *= f; 
}

template<class T>
inline void write(T x)
{
    
    
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int get(double x)
{
    
    
	return lower_bound(alls, alls + m, x) - alls;
}

void build(int u, int l, int r)
{
    
    
	tr[u] = {
    
    l, r};
	if(l >= r) return;
	int mid = l + r >> 1;
	build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r);
}

void pushup(int u)
{
    
    
	if(tr[u].cnt)
	{
    
    
		if(tr[u].cnt & 1)
		{
    
    
			tr[u].len1 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
			tr[u].len2 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
			tr[u].len1 += alls[tr[u].r + 1] - alls[tr[u].l] - tr[u].len1 - tr[u].len2;
		}
		else
		{
    
    
			tr[u].len2 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
			tr[u].len1 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
			tr[u].len2 += alls[tr[u].r + 1] - alls[tr[u].l] - tr[u].len1 - tr[u].len2;
		}
	}
	else if(tr[u].l != tr[u].r)
	{
    
    
		tr[u].len1 = tr[u << 1].len1 + tr[u << 1 | 1].len1;
		tr[u].len2 = tr[u << 1].len2 + tr[u << 1 | 1].len2;
	}
	else tr[u].len1 = tr[u].len2 = 0;
}

void modify(int u, int l, int r, int k)
{
    
    
	if(tr[u].l >= l && tr[u].r <= r)
	{
    
    
		tr[u].cnt += k;
		pushup(u);
		return;
	}
	
	int mid = tr[u].l + tr[u].r >> 1;
	if(l <= mid) modify(u << 1, l, r, k);
	if(r > mid) modify(u << 1 | 1, l, r, k);
	pushup(u);
}

int main()
{
    
    
	
	scanf("%d", &n);
	
	m = 0;
	for(int i = 0; i < n; i ++ )
	{
    
    
		int x1, y1, x2, y2;
		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
		alls[m] = y1; seg[m ++ ] = {
    
    x1, y1, y2, 1};
		alls[m] = y2; seg[m ++ ] = {
    
    x2, y1, y2, -1};
	}
	
	sort(seg, seg + m);
	
	sort(alls, alls + m);
	m = unique(alls, alls + m) - alls;
	
	build(1, 0, m - 2);
	
	ll res1 = 0, res2 = 0;
	for(int i = 0; i < n << 1; i ++ )
	{
    
    
		if(i)
		{
    
    
			res1 += tr[1].len1 * 1ll * (seg[i].x - seg[i - 1].x);
			res2 += tr[1].len2 * 1ll * (seg[i].x - seg[i - 1].x);
		}
		modify(1, get(seg[i].y1), get(seg[i].y2) - 1, seg[i].k);
	}
	
	printf("%lld\n%lld\n", res1, res2);

	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44882261/article/details/113208295