教练给我们打的离线(
数据分治忘删,多 solve 一次,明明复杂度 O(n^3) 偏偏不想压空间 敬重桥廊
不挂的话,70+100+50+50,挂了是 70+100+0+0/cy
A
神笔题,不说了,没意义。
B
你会想要树形 dp,但是你发现其实儿子的子树(除去儿子)对当前答案没有任何影响,于是你会想到我们可以钦定点,然后仅保留这个点和这个点的儿子,钦定这些点是否跳,来得到答案。不重不漏考虑其他点乱跳,即我们只是选取了其一部分来观察这一部分对答案的贡献而已。
然后你会发现你要枚举子集,然后你发现是异或,然后典中典,枚举位,组合数一下就可以了。
D

假如你不会线段树维护分段函数,假如你不会不带 log 的合并,建议跟我一样分块,但是块长和询问次数你要卡好。
显然我们有 Blogn=nB+B,解得 B=√nlogn−1,很厉害啊。
然后我试了一下 B=√n,发现只能 55。充分说明了平衡的重要性(
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=(int)(3e5+5),M=5002;
struct node {
int op,x;
}a[N];
struct nd {
int L,R,b,lv,rv;
nd() {
}
nd(int xL,int xR,int xb,int xlv,int xrv) {
L=xL; R=xR; b=xb; lv=xlv; rv=xrv;
}
}val[M];
int n,q,bl,id[N],L[M],R[M];
int qry(int idx,int x) {
for(int i=L[idx];i<=R[idx];i++) {
if(a[i].op==1) x+=a[i].x;
else if(a[i].op==2) x=min(x,a[i].x);
else x=max(x,a[i].x);
} return x;
}
nd query(int idx) {
int L=1,R=(int)(1e8),q1=qry(idx,1),q2=qry(idx,2),qR=qry(idx,R),qR1=qry(idx,R-1);
if(q1!=q2) {
if(qR!=qR1) {
int qwq=q1-1;
return nd(1,(int)(1e8),qwq,0,0);
} else {
int l=1,r=(int)(1e8),res=0,qwq=qR;
while(l<=r) {
int mid=(l+r)>>1;
if(qry(idx,mid)==qwq) res=mid,r=mid-1;
else l=mid+1;
}
int b=qry(idx,res-1)-(res-1);
return nd(1,res-1,b,0,qR);
}
} else {
if(qR!=qR1) {
int l=1,r=(int)(1e8),res=0,qwq=q1;
while(l<=r) {
int mid=(l+r)>>1;
if(qry(idx,mid)==qwq) res=mid,l=mid+1;
else r=mid-1;
}
int b=qry(idx,res+1)-(res+1);
return nd(res+1,(int)(1e8),b,q1,0);
} else {
int l=1,r=(int)(1e8),qwq=q1,res=0;
while(l<=r) {
int mid=(l+r)>>1;
if(qry(idx,mid)==qwq) res=mid,l=mid+1;
else r=mid-1;
}
L=res+1;
l=1; r=(int)(1e8); qwq=qR; res=0;
while(l<=r) {
int mid=(l+r)>>1;
if(qry(idx,mid)==qwq) res=mid,r=mid-1;
else l=mid+1;
}
R=res-1;
qwq=qry(idx,L)-L;
return nd(L,R,qwq,q1,qR);
}
}
}
int queryx(int idx,int x) {
if(val[idx].L<=x&&x<=val[idx].R) return x+val[idx].b;
if(x<val[idx].L) return val[idx].lv;
return val[idx].rv;
}
int qryx(int x) {
for(int i=1;i<=id[n];i++) {
x=queryx(i,x);
}
return x;
}
signed main() {
cin.tie(0); ios::sync_with_stdio(false);
cin>>n; bl=sqrt(n/max(1,(int)log2(n)-1));
for(int i=1;i<=n;i++) {
cin>>a[i].op>>a[i].x; id[i]=(i-1)/bl+1;
}
for(int i=1;i<=id[n];i++) L[i]=(i-1)*bl+1,R[i]=i*bl;
for(int i=1;i<=id[n];i++) val[i]=query(i);
cin>>q;
while(q--) {
int op; cin>>op;
if(op!=4) {
int x,y; cin>>x>>y;
a[x].op=op; a[x].x=y;
val[id[x]]=query(id[x]);
} else {
int x; cin>>x;
cout<<qryx(x)<<'\n';
}
}
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效