首页 > 其他分享 >题解 gym102900J 【Octasection】

题解 gym102900J 【Octasection】

时间:2024-02-28 22:48:39浏览次数:28  
标签:rs int 题解 gym102900J tree chkmaxl chkminr push Octasection

代码:

#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <cstdio>

using namespace std;

typedef struct Rectangle_tag {
	int x1;
	int x2;
	int y1;
	int y2;
	Rectangle_tag(int x1_, int x2_, int y1_, int y2_){
		x1 = x1_;
		x2 = x2_;
		y1 = y1_;
		y2 = y2_;
	}
} Rectangle;

int cnt1 = 0, cnt2 = 0, cnt3 = 0;
int lsh1[100007], lsh2[100007], lsh3[100007];

namespace SecondD {
	typedef struct {
		int l;
		int r;
		int chkmaxl;
		int chkminr;
		int minl;
		int maxl;
		int minr;
		int maxr;
		pair<int, int> pr1;
		pair<int, int> pr2;
		pair<int, int> pr3;
	} SegmentTreeNode;

	typedef struct StackNode_tag {
		int tm;
		int pos;
		SegmentTreeNode info;
		StackNode_tag(int tm_, int pos_, SegmentTreeNode info_){
			tm = tm_;
			pos = pos_;
			info = info_;
		}
	} StackNode;

	int top = 0, tm;
	SegmentTreeNode tree[400007];
	stack<StackNode> s;

	inline void update(int x){
		int ls = x * 2, rs = x * 2 + 1;
		tree[x].minl = min(tree[ls].minl, tree[rs].minl);
		tree[x].maxl = max(tree[ls].maxl, tree[rs].maxl);
		tree[x].minr = min(tree[ls].minr, tree[rs].minr);
		tree[x].maxr = max(tree[ls].maxr, tree[rs].maxr);
		tree[x].pr1 = min(tree[ls].pr1, tree[rs].pr1);
		tree[x].pr2 = max(tree[ls].pr2, tree[rs].pr2);
		tree[x].pr3 = max(tree[ls].pr3, tree[rs].pr3);
	}

	void build(int x, int l, int r){
		tree[x].l = l;
		tree[x].r = r;
		tree[x].chkmaxl = 0;
		tree[x].chkminr = 0x7fffffff;
		if (l == r){
			tree[x].minl = tree[x].maxl = 0;
			tree[x].minr = tree[x].maxr = cnt3;
			tree[x].pr1 = make_pair(0, l);
			tree[x].pr2 = tree[x].pr3 = make_pair(cnt3, l);
			return;
		}
		int mid = (l + r) >> 1;
		build(x * 2, l, mid);
		build(x * 2 + 1, mid + 1, r);
		update(x);
	}

	inline void push(int x){
		s.push(StackNode(tm, x, tree[x]));
	}
	
	inline bool check(int x){
		return tree[x].chkmaxl != 0 || tree[x].chkminr != 0x7fffffff;
	}

	inline void push_chkmaxl(int x, int k){
		tree[x].chkmaxl = tree[x].minl = tree[x].maxl = tree[x].pr1.first = k;
		tree[x].pr3 = make_pair(tree[x].pr2.first - k, tree[x].pr2.second);
	}

	inline void push_chkminr(int x, int k){
		tree[x].chkminr = tree[x].minr = tree[x].maxr = tree[x].pr2.first = k;
		tree[x].pr3 = make_pair(k - tree[x].pr1.first, tree[x].pr1.second);
	}

	inline void pushdown(int x){
		int ls = x * 2, rs = x * 2 + 1;
		if (tree[x].chkmaxl != 0){
			push_chkmaxl(ls, tree[x].chkmaxl);
			push_chkmaxl(rs, tree[x].chkmaxl);
			tree[x].chkmaxl = 0;
		}
		if (tree[x].chkminr != 0x7fffffff){
			push_chkminr(ls, tree[x].chkminr);
			push_chkminr(rs, tree[x].chkminr);
			tree[x].chkminr = 0x7fffffff;
		}
	}

	void chkmaxl(int x, int l, int r, int k){
		if (tree[x].minl >= k) return;
		push(x);
		if (l <= tree[x].l && tree[x].r <= r && tree[x].maxl < k){
			push_chkmaxl(x, k);
			return;
		}
		int mid = (tree[x].l + tree[x].r) >> 1;
		if (check(x)){
			push(x * 2);
			push(x * 2 + 1);
			pushdown(x);
		}
		if (l <= mid) chkmaxl(x * 2, l, r, k);
		if (r > mid) chkmaxl(x * 2 + 1, l, r, k);
		update(x);
	}

	void chkminr(int x, int l, int r, int k){
		if (tree[x].maxr <= k) return;
		push(x);
		if (l <= tree[x].l && tree[x].r <= r && tree[x].minr > k){
			push_chkminr(x, k);
			return;
		}
		int mid = (tree[x].l + tree[x].r) >> 1;
		if (check(x)){
			push(x * 2);
			push(x * 2 + 1);
			pushdown(x);
		}
		if (l <= mid) chkminr(x * 2, l, r, k);
		if (r > mid) chkminr(x * 2 + 1, l, r, k);
		update(x);
	}

	int getl(int x, int pos){
		if (tree[x].l == tree[x].r) return tree[x].minl;
		pushdown(x);
		if (pos <= ((tree[x].l + tree[x].r) >> 1)) return getl(x * 2, pos);
		return getl(x * 2 + 1, pos);
	}

	inline bool rollback(){
		if (s.empty()) return false;
		StackNode cur = s.top();
		if (cur.tm != tm) return false;
		s.pop();
		tree[cur.pos] = cur.info;
		return true;
	}
}

namespace FirstD {
	typedef struct {
		int l;
		int r;
		vector<Rectangle> v;
	} Node;

	Node tree[400007];

	void build(int x, int l, int r){
		tree[x].l = l;
		tree[x].r = r;
		if (l == r) return;
		int mid = (l + r) >> 1;
		build(x * 2, l, mid);
		build(x * 2 + 1, mid + 1, r);
	}

	void insert(int x, int l, int r, Rectangle rec){
		if (l <= tree[x].l && tree[x].r <= r){
			tree[x].v.push_back(rec);
			return;
		}
		int mid = (tree[x].l + tree[x].r) >> 1;
		if (l <= mid) insert(x * 2, l, r, rec);
		if (r > mid) insert(x * 2 + 1, l, r, rec);
	}

	void dfs(int x){
		SecondD::tm++;
		for (register Rectangle i : tree[x].v){
			if (i.x1 > 1){
				SecondD::chkmaxl(1, 1, i.x1 - 1, i.y1);
				SecondD::chkminr(1, 1, i.x1 - 1, i.y2);
			}
			if (i.x2 < cnt2){
				SecondD::chkmaxl(1, i.x2 + 1, cnt2, i.y1);
				SecondD::chkminr(1, i.x2 + 1, cnt2, i.y2);
			}
		}
		if (tree[x].l == tree[x].r){
			if (SecondD::tree[1].pr3.first >= 0){
				cout << "YES" << endl;
				cout << lsh1[tree[x].l] << " " << lsh2[SecondD::tree[1].pr3.second] << " " << lsh3[SecondD::getl(1, SecondD::tree[1].pr3.second)];
				exit(0);
			}
		} else {
			dfs(x * 2);
			dfs(x * 2 + 1);
		}
		while (SecondD::rollback()) ;
		SecondD::tm--;
	}
}

int l1[100007], r1[100007], l2[100007], r2[100007], l3[100007], r3[100007];

int main(){
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++){
		scanf("%d %d %d %d %d %d", &l1[i], &r1[i], &l2[i], &r2[i], &l3[i], &r3[i]);
		lsh1[++cnt1] = l1[i];
		lsh2[++cnt2] = l2[i];
		lsh3[++cnt3] = l3[i];
	}
	sort(lsh1 + 1, lsh1 + cnt1 + 1);
	cnt1 = unique(lsh1 + 1, lsh1 + cnt1 + 1) - lsh1 - 1;
	sort(lsh2 + 1, lsh2 + cnt2 + 1);
	cnt2 = unique(lsh2 + 1, lsh2 + cnt2 + 1) - lsh2 - 1;
	sort(lsh3 + 1, lsh3 + cnt3 + 1);
	cnt3 = unique(lsh3 + 1, lsh3 + cnt3 + 1) - lsh3 - 1;
	for (int i = 1; i <= n; i++){
		l1[i] = lower_bound(lsh1 + 1, lsh1 + cnt1 + 1, l1[i]) - lsh1;
		r1[i] = upper_bound(lsh1 + 1, lsh1 + cnt1 + 1, r1[i]) - lsh1 - 1;
		l2[i] = lower_bound(lsh2 + 1, lsh2 + cnt2 + 1, l2[i]) - lsh2;
		r2[i] = upper_bound(lsh2 + 1, lsh2 + cnt2 + 1, r2[i]) - lsh2 - 1;
		l3[i] = lower_bound(lsh3 + 1, lsh3 + cnt3 + 1, l3[i]) - lsh3;
		r3[i] = upper_bound(lsh3 + 1, lsh3 + cnt3 + 1, r3[i]) - lsh3 - 1;
	}
	FirstD::build(1, 1, cnt1);
	for (register int i = 1; i <= n; i++){
		Rectangle rec(l2[i], r2[i], l3[i], r3[i]);
		if (l1[i] > 1) FirstD::insert(1, 1, l1[i] - 1, rec);
		if (r1[i] < cnt1) FirstD::insert(1, r1[i] + 1, cnt1, rec);
	}
	SecondD::build(1, 1, cnt2);
	FirstD::dfs(1);
	cout << "NO";
	return 0;
}

标签:rs,int,题解,gym102900J,tree,chkmaxl,chkminr,push,Octasection
From: https://www.cnblogs.com/Leasier/p/18042183

相关文章

  • 24冬网络流复习题解
    A是谁瞪了半个小时不会*2000呀,是谁呀是谁呀。感觉这题比部分紫题都难。。。首先发现选取字符的顺序并不重要,所以\(t\)可以看成\(26\)个字符要选的个数。设字符\(c\)出现了\(x\)次,那么直接向汇点连流量为\(x\)费用为\(0\)的边。然后考虑\(s_i\)与每个字符的关......
  • 2024年2月28号题解
    P4994终于结束的起点解题思路通过加法同余原理可以知道f[i]%m==0,那么f[i-1]%m=1,所有把f[i+1]%m=1转换成了f[i-1]%m=1的问题那么只需要填好斐波那契数列再判断就可以了,又因为斐波那契可能会超出int的范围那么我们对每一项斐波那契再取模就可以了代码......
  • 旅游景点 Tourist Attractions (壮压 DP)题解
    简化题意题目链接——不卡内存班题目链接——卡内存版给定\(n\)个点和\(m\)条边组成的无向图,按照一定限制要求停留\(2\simk+1\)共\(k\)个点(可以经过但不停留),求最短的从\(1\)出发到\(n\)的路径长。限制情况如下:共有\(q\)个限制,接下来\(q\)行,每行两个数\(x......
  • CF1408H Rainbow Triples 题解
    Description给定长度为\(n\)的序列\(p\)找出尽可能多的三元组\((a_i,b_i,c_i)\)满足:\(1\lea_i<b_i<c_i\len\)\(p_{a_i}=p_{c_i}=0\),\(p_{b_i}\ne0\)\(p_{b_i}\)互不相同。所有的\(a_i,b_i,c_i\)互不相同。输出最多可以选出多少个三元组,多组数据。\(\sumn\le......
  • P10160 [DTCPC 2024] Ultra 题解
    【题目描述】给你一个\(01\)序列,你可以进行如下操作若干次(或零次):将序列中形如\(101\cdots01\)的一个子串(即\(1(01)^k\),\(k\ge1\))替换成等长的\(010\cdots10\)(即\(0(10)^k\))。你要操作使得\(1\)的个数尽可能少,输出最少的\(1\)的个数。【思路】一开始看到这道题......
  • 数据类型拓展与面试题解读
    整数拓展进制:在平时咱们生活中经常见到的例如通用于电脑识别的二进制、咱们生活中常用的十进制、工作中常见的八进制与十六进制。二进制:通常会以0b开头十进制:咱们生活中的数字八进制:通常以0开头十六进制:通常以0x开头​ 浮点数拓展(float、double)试题举例银行......
  • Codeforces Round 929 (Div. 3) 题解(D-G)
    比赛链接:https://codeforces.com/contest/1933官解暂未放出。质量不错的一场D3。CF1933D.TurtleTenacity:ContinualMods题意将数组\(a_{1..n}\ge1\)重排,问是否能使\(((a_1\mathbin{\rmmod}a_2)\mathbin{\rmmod}a_3)\cdots\mathbin{\rmmod}a_n\ne0\)......
  • 题解 P10196【[USACO24FEB] Lazy Cow P】
    总算铂金组场切一题。似乎做麻烦了,而且常数蛮大的,但是没啥思维难度,记录一下。对于每一个需求,我们将其放置在平面直角坐标系的\((m_i,b_i)\)位置。另外,自然有一个\((0,0)\)需求,也同样处理这个点。我们需要支持插入一个点的操作,并维护出答案。先考虑不需要动态插点,只在最后求......
  • 第十四届蓝桥杯个人题解
    a幸运的数主要是思路 遍历1-100000000每一层循环,首先将其每一位分到数组里,并记录位数,如果是偶数位再接着往下,比较前半和后半是否相等:通过加减最后结果是否为零来判断intmain(){  intnum=0;  for(inti=1;i<100000000;i++)  {    ints[9]={0};......
  • ABC338G evall 题解
    题意:给定一个由数字和加号和乘号组成的字符串,求出\(\sums(i,j)\)。其中\(s(i,j)\)表示\(i\)到\(j\)字符组成的表达式的值。考虑\(\text{dp}\)。设\(dp_{i}\)表示以\(i\)为起点的所有表达式的值之和。那么我们考虑以一些加号作为分界点来转移。假设\(i\)右边最......