ICode9

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

题解 联

2021-07-23 09:04:35  阅读:150  来源: 互联网

标签:qr ++ 题解 long usize uni define


传送门

这题考场上居然调出来了没炸细节……

第一思路是链表,然而链表上没法二分所以是\(n^2\)的
要不是数据范围很大就可以用线段树了
考虑离散化,但离散化完两个不连续的位置可能会被离散得连续了
所以把每个\(l-1, l, r, r+1\)全扔进去离散化,同时注意把1也扔进去就行了
我打的是全0/1和异或标记,注意这两个标记不共存即可

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long 
#define ld long double
#define usd unsigned
#define ull unsigned long long
#define int long long 

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
char buf[1<<21], *p1=buf, *p2=buf;
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int m;

namespace force{
	bool vis[N];
	void solve() {
		for (int i=1,t,l,r; i<=m; ++i) {
			t=read(); l=read(); r=read();
			if (t==1) {
				for (int j=l; j<=r; ++j) vis[j]=1;
			}
			else if (t==2) {
				for (int j=l; j<=r; ++j) vis[j]=0;
			}
			else {
				for (int j=l; j<=r; ++j) vis[j]^=1;
			}
			for (int j=1; j<N; ++j) if (!vis[j]) {printf("%lld\n", j); break;}
		}
		exit(0);
	}
}

namespace task1{
	int uni[N*10], usize;
	int qt[N], ql[N], qr[N];
	const int SIZE=(N*8)<<2;
	int tl[SIZE], tr[SIZE];
	bool tag0[SIZE], tag1[SIZE], tagx[SIZE];
	#define tl(p) tl[p]
	#define tr(p) tr[p]
	#define tag0(p) tag0[p]
	#define tag1(p) tag1[p]
	#define tagx(p) tagx[p]
	void build(int p, int l, int r) {
		tl(p)=l; tr(p)=r; tag0(p)=1;
		if (l>=r) return ;
		int mid=(l+r)>>1;
		build(p<<1, l, mid);
		build(p<<1|1, mid+1, r);
	}
	void spread(int p) {
		if (tag0(p) || tag1(p)) {
			tag0(p<<1)=tag0(p), tag1(p<<1)=tag1(p), tagx(p<<1)=0;
			tag0(p<<1|1)=tag0(p), tag1(p<<1|1)=tag1(p), tagx(p<<1|1)=0;
			//assert(!tagx(p));
			return ;
		}
		if (!tagx(p)) return ;
		
		//assert(!(tag0(p)&&tag1(p)));
		if (tag0(p<<1)||tag1(p<<1)) {swap(tag0(p<<1), tag1(p<<1)); tagx(p<<1)=0;}
		else tagx(p<<1)^=1;
		
		if (tag0(p<<1|1)||tag1(p<<1|1)) {swap(tag0(p<<1|1), tag1(p<<1|1)); tagx(p<<1|1)=0;}
		else tagx(p<<1|1)^=1;
		tagx(p)=0;
	}
	void upd(int p, int ql, int qr, int dat) {
		//cout<<"upd: "<<p<<' '<<tl(p)<<' '<<tr(p)<<' '<<ql<<' '<<qr<<' '<<dat<<endl;
		if (ql<=tl(p)&&qr>=tr(p)) {
			if (dat==0) {tag0(p)=tag1(p)=tagx(p)=0; tag0(p)=1; return ;}
			if (dat==1) {tag0(p)=tag1(p)=tagx(p)=0; tag1(p)=1; return ;}
			if (dat==2) {
				//cout<<"x1: "<<p<<' '<<tl(p)<<' '<<tr(p)<<' '<<tag0(p)<<' '<<tag1(p)<<' '<<tagx(p)<<endl;
				if (tag0(p)||tag1(p)) swap(tag0(p), tag1(p)), tagx(p)=0; //, cout<<"case1"<<endl;
				else tagx(p)^=1; //, cout<<"case2"<<endl;
				//cout<<"x2: "<<p<<' '<<tl(p)<<' '<<tr(p)<<' '<<tag0(p)<<' '<<tag1(p)<<' '<<tagx(p)<<endl;
				return ;
			}
		}
		spread(p);
		tag0(p)=tag1(p)=0;
		//cout<<"zero "<<p<<endl;
		int mid=(tl(p)+tr(p))>>1;
		if (ql<=mid) upd(p<<1, ql, qr, dat);
		if (qr>mid) upd(p<<1|1, ql, qr, dat);
	}
	int query(int p) {
		//cout<<"query "<<p<<' '<<tl(p)<<' '<<tr(p)<<endl;
		if (!p) return -1;
		//assert(!(tag0(p)&&tag1(p)));
		if (tag0(p)) return tl(p);
		if (tag1(p)) return -1;
		if (tl(p)==tr(p)) return -1;
		spread(p);
		int t, ans=-1;
		t=query(p<<1);
		if (t!=-1) {
			if (ans==-1) ans=t;
			else ans=min(ans, t);
		}
		if (ans!=-1) return ans;
		t=query(p<<1|1);
		if (t!=-1) {
			if (ans==-1) ans=t;
			else ans=min(ans, t);
		}
		return ans;
	}
	void solve() {
		//cout<<double(sizeof(tl)*4+sizeof(uni))/1024/1024<<endl;
		for (int i=1; i<=m; ++i) {
			qt[i]=read(); ql[i]=read(); qr[i]=read();
			uni[++usize]=ql[i]; if (ql[i]-1>0) uni[++usize]=ql[i]-1; uni[++usize]=ql[i]+1;
			uni[++usize]=qr[i]; if (qr[i]-1>0) uni[++usize]=qr[i]-1; uni[++usize]=qr[i]+1;
		}
		uni[++usize]=1;
		sort(uni+1, uni+usize+1);
		usize=unique(uni+1, uni+usize+1)-uni-1;
		//cout<<"usize: "<<usize<<endl;
		//cout<<"uni: "; for (int i=1; i<=usize; ++i) cout<<uni[i]<<' '; cout<<endl;
		build(1, 1, usize+1);
		int tsk[]={-1, 1, 0, 2};
		for (int i=1,t; i<=m; ++i) {
			upd(1, lower_bound(uni+1, uni+usize+1, ql[i])-uni, lower_bound(uni+1, uni+usize+1, qr[i])-uni, tsk[qt[i]]);
			//cout<<"upd: "<<lower_bound(uni+1, uni+usize+1, ql[i])-uni<<' '<<lower_bound(uni+1, uni+usize+1, qr[i])-uni<<' '<<tsk[qt[i]]<<endl;
			t = query(1);
			//cout<<"t: "<<t<<endl;
			printf("%lld\n", uni[t]);
		}
		exit(0);
	}
}

signed main()
{
	#ifdef DEBUG
	freopen("1.in", "r", stdin);
	#endif
	
	m=read();
	//force::solve();
	task1::solve();

	return 0;
}

标签:qr,++,题解,long,usize,uni,define
来源: https://www.cnblogs.com/narration/p/15047308.html

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

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

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

ICode9版权所有