题解 暗星人

传送门

这空间卡的属实离谱

首先有个显然的树套树思路:将时间和区间都拆成 log 段查询,时间和空间复杂度都是两个 log
然而空间限制是两个 G
所以就开始码了对不对
所以就 MLE 了对不对
于是我们发现由于出题人的精心设计这点空间只够跑 \(3e5\) 次操作里的 \(2.9e5\)
离谱

  • 树套树将其中一棵树换成分块可以在劣化时间复杂度的同时优化空间复杂度

然后正解用分散层叠可以做到一个 log,咕了

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 300010
#define M 1000010
#define K 20000000
#define ll long long
#define fir first
#define sec second
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
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 n, m, typ;
const ll mod=2677114440;
int L[M], R[M], a[M], l[M], r[M], X[M], x[M], len;
// int tl[N<<2], tr[N<<2], rot[N<<2], bel[M], cnt;
int lson[K], rson[K], bel[M], rot[M], lside[M], tot;
unsigned mx[K], maxn, b[M];

#define tl(p) tl[p]
#define tr(p) tr[p]
#define rot(p) rot[p]
#define ls(p) lson[p]
#define rs(p) rson[p]
#define val(p) val[p]
#define tag(p) tag[p]
#define mx(p) mx[p]

struct line{unsigned k, b; line(){} line(unsigned x, unsigned y):k(x),b(y){} inline ll qval(ll x) {return (1ll*k*x%mod+b)%mod;}}val[K], tag[K];
inline line operator * (line a, line b) {return {1ll*a.k*b.k%mod, (1ll*b.k*a.b+b.b)%mod};}

namespace seg1{
	namespace seg3{
		void spread(int p, int gl, int gr) {
			if (tag(p).k==1&&!tag(p).b) return ;
			if (!ls(p)) ls(p)=++tot, val(ls(p))=tag(ls(p))={1, 0};
			if (!rs(p)) rs(p)=++tot, val(rs(p))=tag(rs(p))={1, 0};
			int mid=(gl+gr)>>1;
			val(ls(p))=val(ls(p))*tag(p); if (gl!=mid) tag(ls(p))=tag(ls(p))*tag(p);
			val(rs(p))=val(rs(p))*tag(p); if (mid+1!=gr) tag(rs(p))=tag(rs(p))*tag(p);
			tag(p)={1, 0};
		}
		void upd(int& p, int gl, int gr, int& l, int& r, line& dat, unsigned& val2) {
			// cerr<<"upd2: "<<p<<' '<<gl<<' '<<gr<<' '<<l<<' '<<r<<endl;
			if (!p) p=++tot, val(p)=tag(p)={1, 0};
			if (l<=gl&&r>=gr) {val(p)=val(p)*dat; tag(p)=tag(p)*dat; mx(p)=max(mx(p), val2); return ;}
			spread(p, gl, gr);
			int mid=(gl+gr)>>1;
			if (l<=mid) upd(ls(p), gl, mid, l, r, dat, val2);
			if (r>mid) upd(rs(p), mid+1, gr, l, r, dat, val2);
		}
		line query(int p, int gl, int gr, int pos) {
			if (!p) return {1, 0};
			maxn=max(maxn, mx(p));
			if (gl==gr) return val(p);
			// spread(p);
			int mid=(gl+gr)>>1;
			if (pos<=mid) {
				if (ls(p)) return query(ls(p), gl, mid, pos)*tag(p);
				else return val(p);
			}
			else {
				if (rs(p)) return query(rs(p), mid+1, gr, pos)*tag(p);
				else return val(p);
			}
			// if (pos<=mid) return query(ls(p), gl, mid, pos);
			// else return query(rs(p), mid+1, gr, pos);
		}
	}
	// void build(int p, int l, int r) {
	// 	tl(p)=l; tr(p)=r;
	// 	if (l==r) return ;
	// 	int mid=(l+r)>>1;
	// 	build(p<<1, l, mid);
	// 	build(p<<1|1, mid+1, r);
	// }
	// void upd(int p, int pos, int& l, int& r, line& val, unsigned& val2) {
	// 	// cerr<<"upd: "<<p<<' '<<tl(p)<<' '<<tr(p)<<endl;
	// 	++cnt;
	// 	seg3::upd(rot[p], 1, n, l, r, val, val2);
	// 	if (tl(p)==tr(p)) return ;
	// 	int mid=(tl(p)+tr(p))>>1;
	// 	if (pos<=mid) upd(p<<1, pos, l, r, val, val2);
	// 	else upd(p<<1|1, pos, l, r, val, val2);
	// }
	// line query(int p, int& l, int& r, int& x) {
	// 	if (l<=tl(p)&&r>=tr(p)) return seg3::query(rot[p], 1, n, x);
	// 	int mid=(tl(p)+tr(p))>>1;
	// 	if (l<=mid&&r>mid) return query(p<<1, l, r, x)*query(p<<1|1, l, r, x);
	// 	else if (l<=mid) return query(p<<1, l, r, x);
	// 	else return query(p<<1|1, l, r, x);
	// }
	void build(int p, int l, int r) {
		len=pow(m, 0.58);
		memset(lside, 127, sizeof(lside));
		for (int i=1; i<=m; ++i) bel[i]=(i-1)/len+1, lside[bel[i]]=min(lside[bel[i]], i);
	}
	void upd(int p, int pos, int& l, int& r, line& val, unsigned& val2) {
		int now=bel[pos];
		seg3::upd(rot[now], 1, n, l, r, val, val2);
	}
	line query(int p, int& l, int& r, int& x) {
		int sid=bel[l], eid=bel[r];
		line ans={1, 0};
		if (sid==eid) {
			for (int i=l; i<=r; ++i) if (L[i]<=x&&x<=R[i]) ans=ans*line(a[i], b[i]), maxn=max(maxn, b[i]);
			return ans;
		}
		for (int i=l; bel[i]==sid; ++i) if (L[i]<=x&&x<=R[i]) ans=ans*line(a[i], b[i]), maxn=max(maxn, b[i]);
		for (int i=sid+1; i<eid; ++i) ans=ans*seg3::query(rot[i], 1, n, x);
		for (int i=lside[eid]; i<=r; ++i) if (L[i]<=x&&x<=R[i]) ans=ans*line(a[i], b[i]), maxn=max(maxn, b[i]);
		return ans;
	}
}

// namespace seg2{
// 	namespace seg4{
// 		void upd(int& p, int gl, int gr, int& l, int& r, unsigned dat) {
// 			// cerr<<"upd2: "<<p<<' '<<gl<<' '<<gr<<' '<<l<<' '<<r<<endl;
// 			if (!p) p=++tot;
// 			if (l<=gl&&r>=gr) {mx(p)=max(mx(p), dat); return ;}
// 			int mid=(gl+gr)>>1;
// 			if (l<=mid) upd(ls(p), gl, mid, l, r, dat);
// 			if (r>mid) upd(rs(p), mid+1, gr, l, r, dat);
// 		}
// 		unsigned query(int p, int gl, int gr, unsigned pos) {
// 			if (!p) return 0;
// 			if (gl==gr) return mx(p);
// 			int mid=(gl+gr)>>1;
// 			if (pos<=mid) {
// 				if (ls(p)) return max(query(ls(p), gl, mid, pos), mx(p));
// 				else return mx(p);
// 			}
// 			else {
// 				if (rs(p)) return max(query(rs(p), mid+1, gr, pos), mx(p));
// 				else return mx(p);
// 			}
// 		}
// 	}
// 	void build(int p, int l, int r) {
// 		tl(p)=l; tr(p)=r;
// 		if (l==r) return ;
// 		int mid=(l+r)>>1;
// 		build(p<<1, l, mid);
// 		build(p<<1|1, mid+1, r);
// 	}
// 	void upd(int p, int pos, int& l, int& r, unsigned val) {
// 		// cerr<<"upd: "<<p<<' '<<tl(p)<<' '<<tr(p)<<endl;
// 		seg4::upd(rot[p], 1, n, l, r, val);
// 		if (tl(p)==tr(p)) return ;
// 		int mid=(tl(p)+tr(p))>>1;
// 		if (pos<=mid) upd(p<<1, pos, l, r, val);
// 		else upd(p<<1|1, pos, l, r, val);
// 	}
// 	signed query(int p, int& l, int& r, signed x) {
// 		if (l<=tl(p)&&r>=tr(p)) return seg4::query(rot[p], 1, n, x);
// 		int mid=(tl(p)+tr(p))>>1;
// 		if (l<=mid&&r>mid) return max(query(p<<1, l, r, x), query(p<<1|1, l, r, x));
// 		else if (l<=mid) return query(p<<1, l, r, x);
// 		else return query(p<<1|1, l, r, x);
// 	}
// }

namespace task1{
	void solve() {
		seg1::build(1, 1, m); //seg2::build(1, 1, m);
		line t; ll lst=0;
		for (int i=1; i<=m; ++i) {
			// cerr<<"i: "<<i<<endl;
			// cerr<<"cnt: "<<cnt<<endl;
			// cerr<<"tot: "<<tot<<endl;
			// cerr<<"tot: "<<seg2::seg4::tot<<endl;
			if (typ==0) lst=0;
			L[i]=read()^lst; R[i]=read()^lst; a[i]=read()^lst; b[i]=read()^lst; l[i]=read()^lst; r[i]=read()^lst; X[i]=read()^lst; x[i]=read()^lst;
			seg1::upd(1, i, L[i], R[i], t={a[i], b[i]}, b[i]);
			// seg2::upd(1, i, L[i], R[i], b[i]);
			maxn=0;
			line t=seg1::query(1, l[i], r[i], X[i]);
			// if (i==10014) {
			// 	cout<<"t: "<<t.k<<' '<<t.b<<endl;
			// 	cout<<"qval: "<<t.qval(x[i])<<endl;
			// 	cout<<"qmax: "<<seg2::query(1, l[i], r[i], X[i])<<endl;
			// 	cout<<(lst=(t.qval(x[i])^seg2::query(1, l[i], r[i], X[i])))<<endl;
			// 	exit(0);
			// }
			// exit(0);
			printf("%lld\n", lst=t.qval(x[i])^maxn);
			// cout<<(lst=(t.qval(x[i])^seg2::query(1, l[i], r[i], X[i])))<<endl;
			// exit(0);
		}
		exit(0);
	}
}

signed main()
{
	freopen("dark.in", "r", stdin);
	freopen("dark.out", "w", stdout);

	// cout<<double(sizeof(L)*8+sizeof(tl)*3+sizeof(lson)*5+sizeof(tag))/1000/1000<<endl; exit(0);
	n=read(); m=read(); typ=read();
	// cerr<<n<<endl;
	// force::solve();
	task1::solve();

	return 0;
}
posted @ 2022-01-16 07:12  Administrator-09  阅读(0)  评论(0编辑  收藏  举报