ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JZOJ 5067. 【GDOI2017第二轮模拟day2】有理有据题 (KD-tree+历史最值问题)

2020-08-08 11:31:36  阅读:286  来源: 互联网

标签:5067 JZOJ int max void tree m1 m2 bz


https://gmoj.net/senior/#main/show/5067

题解:

考虑\([l,r]∩[x,y] \ne ∅\)的充要条件是\(max(l,x)\le min(r,y)\)
即\(l \le y且 x \le r\)

那么每次相当于修改矩形内的点。

套上一个K-D tree,问题变成了:

  1. 区间加
  2. 区间赋值
  3. 询问单点历史最大值

这个可以直接lazytag搞定,通过思考一个操作序列需要保留什么东西即可实现。

Code:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int N = 50005;

int n, m, Q;

struct P {
	int x, y, i;
} a[N];

void Init() {
	scanf("%d %d %d", &n, &m, &Q);
	fo(i, 1, n) {
		scanf("%d %d", &a[i].x, &a[i].y);
		if(a[i].x > a[i].y) swap(a[i].x, a[i].y);
		a[i].y = -a[i].y;
		swap(a[i].x, a[i].y);
		a[i].i = i;
	}
}

struct nod {
	bool bz;
	int m1, m2, s;
	nod() { bz = m1 = m2 = s = 0;}
};

void jia(nod &a, int v) {
	if(!a.bz) {
		a.s += v;
		a.m1 = max(a.m1, a.s);
	} else {
		a.s += v;
		a.m2 = max(a.m2, a.s);
	}
}

void fz(nod &a) {
	a.bz = 1;
	a.s = 0;
}

void mer(nod &a, nod b) {
	if(!a.bz) {
		if(!b.bz) {
			a.bz = 0;
			a.m1 = max(a.m1, a.s + b.m1);
			a.s += b.s;
		} else {
			a.bz = 1;
			a.m1 = max(a.m1, a.s + b.m1); 
			a.m2 = b.m2;
			a.s = b.s;
		}
	} else {
		if(!b.bz) {
			a.bz = 1;
			a.m2 = max(a.m2, a.s + b.m1);
			a.s += b.s;
		} else {
			a.bz = 1;
			a.m2 = max(a.m2, max(a.s + b.m1, b.m2));
			a.s = b.s;
		}
	}
}

#define i0 i + i
#define i1 i + i + 1

struct tree {
	int mi[2], mx[2];
	nod v;
} t[N * 4];
int rt = 1;

int o;
int cmp(P a, P b) {
	return o ? a.y < b.y : a.x < b.x;
}

int ia[N];

#define db double
int ca(int x, int y) {
	db s1 = 0, s2 = 0;
	fo(i, x, y) {
		s1 += a[i].x;
		s2 += a[i].y;
	}
	s1 /= (y - x + 1);
	s2 /= (y - x + 1);
	db v1 = 0, v2 = 0;
	#define sqr(x) ((x) * (x))
	fo(i, x, y) {
		v1 += sqr(a[i].x - s1);
		v2 += sqr(a[i].y - s2);
	}
	return v1 > v2 ? 0 : 1;
}

void bt(int i, int x, int y) {
	if(x == y) {
		t[i].mi[0] = t[i].mx[0] = a[x].x;
		t[i].mi[1] = t[i].mx[1] = a[x].y;
		ia[a[x].i] = x;
		return;
	}
	o = ca(x, y)	;
	int m = x + y >> 1;
	nth_element(a + x, a + m, a + y + 1, cmp);
	
	bt(i0, x, m); bt(i1, m + 1, y);
	
	fo(j, 0, 1) {
		t[i].mi[j] = min(t[i0].mi[j], t[i1].mi[j]);
		t[i].mx[j] = max(t[i0].mx[j], t[i1].mx[j]);
	}
}

void down(int i) {
	if(t[i].v.bz || t[i].v.m1 || t[i].v.s) {
		mer(t[i0].v, t[i].v);
		mer(t[i1].v, t[i].v);
		t[i].v = nod();
	}
}

int pl[2], pr[2];

void add(int i, int x, int y) {
	if(t[i].mi[0] > pr[0] || t[i].mi[1] > pr[1]) {
		fz(t[i].v);
		return;
	}
	if(t[i].mx[0] <= pr[0] && t[i].mx[1] <= pr[1]) {
		jia(t[i].v, 1);
		return;
	}
	int m = x + y >> 1; down(i);
	add(i0, x, m); add(i1, m + 1, y);
}

int pz, px;

void ft(int i, int x, int y) {
	if(x == y) {
		px = max(t[i].v.m1, t[i].v.m2);
		return;
	}
	int m = x + y >> 1; down(i);
	if(pz <= m) ft(i0, x, m); else ft(i1, m + 1, y);
}

char str[11];
int x, y;

void cz(int x, int y) {
	if(x > y) swap(x, y);
	x = -x;
	pl[0] = pl[1] = -1e9;
	pr[0] = x, pr[1] = y;
	add(rt, 1, n);
}

int qry(int x) {
	pz = ia[x]; px = 0;
	ft(rt, 1, n);
}

void End() {
	fo(i, 1, m) {
		scanf("%d %d", &x, &y);
		cz(x, y);
	}
	fo(i, 1, Q) {
		scanf("%s", str + 1);
		if(str[1] == 'A') {
			scanf("%d %d", &x, &y);
			cz(x, y);
		}
		if(str[1] == 'C') {
			scanf("%d", &x);
			pp("%d\n", qry(x));
		}
		if(str[1] == 'Q') {
			int s = 0;
			fo(j, 1, n) s ^= qry(j);
			pp("%d\n", s);
		}
	}
}

int main() {
	freopen("bomb.in", "r", stdin);
	freopen("bomb.out", "w", stdout);
	Init();
	bt(rt, 1, n);
	End();
}

标签:5067,JZOJ,int,max,void,tree,m1,m2,bz
来源: https://www.cnblogs.com/coldchair/p/13456949.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有