LG3801 빨간색 환상 마을 트리 라인 + 포함 및 제외

문제 설명

마지막 실패 후, Remilia 다시 Hongwu 돌연변이를 시작하기로 결정하지만, 다시 방지 영적인 꿈을 지배하기 위해, 그녀는 Hongwu 이상한 전투를 해제하기로 결정했다.

우리는 환상의 마을로 간주됩니다 \ (N \ 번 \ M) Hongwu 영역 중 하나가 덮여 시작하지 않았다, 사각형 영역을. 한 지역의 각 서 Remilia, 각각은 전체 행 / 열 전체에 영향을 미칠 수하는 무한 길이의 Hongwu 네 방향 트럭을 발행하지만, 그녀 역의 영역에 영향을주지 않습니다. 밀도가 너무 커서 사라 정착 때문에 두 사람은, Hongwu 충돌을 패치합니다. 이 돌연변이의 인식 Reimu, 결정은 그것을 해결합니다. 그러나 해결하기 전에, 영적 꿈 밀도 Hongwu의 범위를 이해합니다. 두 작업은 간단하게 설명 될 수 있습니다 :

1 x yRemilia 서 좌표 \ ((x, y)는 \ ) 무한 Hongwu 네 방향으로 해제 위치.

2 x1 y1 x2 y2심문 좌상단 \ ((X1, Y1) \) , 우하 점 \ ((X2, Y2) \ ) 사각형 내에는, 영역의 수는 홍 우 덮여있다.


문제 해결

장소는 합의에 서 간주됩니다.

이 개 트리 라인, 라인 유지 보수, 유지 보수 컬럼의 유지 관리, 단일 지점 수정, 쿼리 간격 (펜윅 트리 캔)

집합 \ (R, C는 \) - 행을 나타내고, 열 번호로 덮여, 응답이 (Y1, Y2 $ R \ 배 + C \ 시간 (X2 - X1 + 1) - + 1) 2 \ 시간의 R \ 시간 C $ .

마이너스 두 번 \ (R \ 번 C \) 이유 : 통계의 제거 계급마다.


\ (\ mathrm {코드} \)

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

const int maxn = 100000 + 7;
const int maxm = 200000 + 7;

int n, m, T;

template < typename Tp >
void read(Tp &x) {
	x = 0;char ch = 1;int fh = 1;
	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
	if(ch == '-') fh = -1, ch=getchar();
	while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	x *= fh;
}

void Init(void) {
	read(n); read(m); read(T);
}

struct Segment_Tree {
	#define lfc (x << 1)
	#define rgc ((x << 1) | 1)
	#define mid ((l + r) >> 1)
	int val[maxn << 2];
	void modify(int x, int l, int r, int pos) {
		if(l == r) {
			val[x] = 1 - val[x];
			return ;
		}
		if(pos <= mid) modify(lfc, l, mid, pos);
		else modify(rgc, mid + 1, r, pos);
		val[x] = val[lfc] + val[rgc];
	}
	int query(int x, int l, int r, int L, int R) {
		if(L <= l && r <= R) return val[x];
		if(r < L || l > R) return 0;
		return query(lfc, l, mid, L, R) + query(rgc, mid + 1, r, L, R);
	}
}row, column;


void operator1(void) {
	int x, y;
	read(x); read(y);
	row.modify(1, 1, n, x);
	column.modify(1, 1, m, y);
}

void operator2(void) {
	int x1, x2, y1, y2;
	read(x1); read(y1); read(x2); read(y2);
	int R = row.query(1, 1, n, x1, x2), C = column.query(1, 1, m, y1, y2);
	LL ans = (LL)(y2 - y1 + 1) * (LL)R + (x2 - x1 + 1) *(LL)C - (LL)R * (LL)C * 2ll;
	printf("%lld\n", ans);
}

void Work(void) {
	while(T--) {
		int op; read(op);
		if(op == 1) operator1();
		else operator2();
	}
}

int main(void) {
	Init();
	Work();
	return 0;
}

추천

출처www.cnblogs.com/liubainian/p/12571638.html