题解 暗星人
这空间卡的属实离谱
首先有个显然的树套树思路:将时间和区间都拆成 log 段查询,时间和空间复杂度都是两个 log
然而空间限制是两个 G
所以就开始码了对不对
所以就 MLE 了对不对
于是我们发现由于出题人的精心设计这点空间只够跑 次操作里的 次
离谱
- 树套树将其中一棵树换成分块可以在劣化时间复杂度的同时优化空间复杂度
然后正解用分散层叠可以做到一个 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话