【DS】线段树分治学习笔记
给你一堆操作,每个操作都有自己的影响时间,查询某一时间点的状态。
- 线段树分治:按时间轴将修改保存到 个区间里,将询问离线查询,时刻 的询问就是线段树上根节点走到 后的数据结构。
给你一堆操作,查询一段时间内的状态。
- 线段树分治:按时间轴将修改和查询都保存到 个区间里,时刻 的修改影响线段树上根节点走到 的各个区间,查询就是将这些区间的影响合并。
适用范围:需要的数据结构不支持删除,但是能快速撤销,如 线性基,李超线段树,并查集 等。
P5787 二分图 /【模板】线段树分治
这属于上面的第一种情况。判断二分图用扩展域并查集(注意不能路径压缩)。
点击查看代码
#define pb push_back
const int N=1e5+10;
typedef pair<int,int> pr;
int n,m,k;
int fa[N<<1],siz[N<<1];
vector<pr> q[N<<2];
bool vis[N<<2];
#define ls p<<1
#define rs p<<1|1
void modify(int p,int l,int r,int ql,int qr,int u,int v){
if(ql<=l&&r<=qr)return q[p].pb({u,v}),void();
int mid=(l+r)>>1;
if(ql<=mid)modify(ls,l,mid,ql,qr,u,v);
if(qr>mid)modify(rs,mid+1,r,ql,qr,u,v);
}
int fnd(int x){//要支持撤销操作,不能路径压缩
return fa[x]==x?x:fnd(fa[x]);
}
void undo(vector<pr> a){//撤销
for(pr tmp:a){
siz[tmp.first]-=siz[tmp.second];
fa[tmp.second]=tmp.second;
}
}
void query(int p,int l,int r){
vector<pr> upd;
if(vis[p]){
for(pr tmp:q[p]){
int u=fnd(tmp.first),v=fnd(tmp.second),
uu=fnd(tmp.first+n),vv=fnd(tmp.second+n);
if(u==v){vis[p]=0;break;}
if(siz[u]<siz[vv])swap(u,vv);
if(siz[v]<siz[uu])swap(v,uu);
fa[vv]=u,siz[u]+=siz[vv];fa[uu]=fa[v],siz[v]+=siz[uu];
upd.pb({u,vv}),upd.pb({v,uu});
}
}
if(l==r)return vis[p]?printf("Yes\n"):printf("No\n"),undo(upd),void();
vis[ls]=vis[rs]=vis[p];
int mid=(l+r)>>1;
query(ls,l,mid),query(rs,mid+1,r);
undo(upd);
}
int main(){
read(n),read(m),read(k);
for(int i=1;i<=n*2;++i)fa[i]=i,siz[i]=1;
int u,v,l,r;
while(m--){
read(u),read(v),read(l),read(r);
modify(1,1,k,l+1,r,u,v);
}vis[1]=1,query(1,1,k);
return 0;
}
P4585 [FJOI2015]火星商店问题
这属于上面的第二种情况。求异或最大值用可持久化 trie,对于每个区间的修改建出 trie 然后更新包含该区间的询问。
点击查看代码
#define pb push_back
const int N=1e5+10;
typedef pair<int,int> pr;
int n,m;
struct qry{int l,r,x,id;};
vector<qry> q[N<<2];
vector<pr> upd[N<<2];
int ans[N];
struct trie{
int cnt=0,rt[N],son[N<<5][2],siz[N<<5];
void clear(){memset(son,0,cnt+10),memset(siz,0,cnt+10);cnt=0;}
void insert(int &cur,int pre,int val,int bit=16){
cur=++cnt;
son[cur][0]=son[pre][0],son[cur][1]=son[pre][1],siz[cur]=siz[pre]+1;
if(bit==-1)return;
int id=(val>>bit)&1;
insert(son[cur][id],son[pre][id],val,bit-1);
}
int query(int l,int r,int val,int bit=16){
if(bit==-1||!(siz[r]-siz[l]))return 0;
int id=(val>>bit)&1,qwq=id^1;
if(siz[son[r][qwq]]-siz[son[l][qwq]]>0)return (1<<bit)+query(son[l][qwq],son[r][qwq],val,bit-1);
return query(son[l][id],son[r][id],val,bit-1);
}
}all,now;
#define ls p<<1
#define rs p<<1|1
void modify(int p,int l,int r,int pos,pr v){
upd[p].pb(v);
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)modify(ls,l,mid,pos,v);
else modify(rs,mid+1,r,pos,v);
}
void query(int p,int l,int r,int ql,int qr,qry v){
if(ql<=l&&r<=qr)return q[p].pb(v),void();
int mid=(l+r)>>1;
if(ql<=mid)query(ls,l,mid,ql,qr,v);
if(qr>mid)query(rs,mid+1,r,ql,qr,v);
}
void calc(int p){
now.clear();sort(upd[p].begin(),upd[p].end());
//按编号顺序加入方便查询
int pre=0;
for(pr tmp:upd[p]){
now.insert(now.rt[tmp.first],now.rt[pre],tmp.second);
pre=tmp.first;
}
for(qry tmp:q[p]){
int l=lower_bound(upd[p].begin(),upd[p].end(),make_pair(tmp.l,0))-upd[p].begin();
int r=lower_bound(upd[p].begin(),upd[p].end(),make_pair(tmp.r,114514))-upd[p].begin()-1;
if(r<0)continue;
l=l?upd[p][l-1].first:0,r=upd[p][r].first;
ans[tmp.id]=max(ans[tmp.id],now.query(now.rt[l],now.rt[r],tmp.x));
}
}
void solve(int p,int l,int r){
calc(p);
if(l==r)return;
int mid=(l+r)>>1;
solve(ls,l,mid);solve(rs,mid+1,r);
}
int main(){
read(n),read(m);memset(ans,-1,sizeof ans);
for(int i=1,x;i<=n;++i)read(x),all.insert(all.rt[i],all.rt[i-1],x);
int now=0,op,l,r,d,x;
for(int i=1;i<=m;++i){
read(op);now+=!op;
if(!op){
read(d),read(x);
modify(1,0,m,now,{d,x});
}else {
read(l),read(r),read(x),read(d);
ans[i]=all.query(all.rt[l-1],all.rt[r],x);
if(d)query(1,0,m,max(1,now-d+1),now,(qry){l,r,x,i});
}
}solve(1,0,m);
for(int i=1;i<=m;++i)if(ans[i]!=-1)printf("%d\n",ans[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】