「BalticOI 2021 Day1」Inside information
「BalticOI 2021 Day1」Inside information
题目大意
有 个集合 ,一开始 。
执行 个操作:
- 选择 ,令 。
- 对于 ,回答 。
- 对于 ,回答 。
保证操作 恰好出现 次,且所有边 构成一棵树。
分析
题目保证或操作构成一棵树,考虑一个熟悉的问题:
每次选择两个点连边,维护连通块中的点集。
用并查集+线段树合并处理。
在这道题中,点之间的关系无法用并查集处理,但依然可以考虑线段树合并。
容易发现,每次被合并的树 ,它们的节点集合都是 的子集,其中 表示 所在连通块的点集。
而由上面的提到的经典问题,我们知道合并 的线段树合并复杂度为 。
而合并 的线段树合并复杂度不高于合并 ,因此不高于 。
因此 操作可以直接用线段树合并处理,由于一棵树可能被合并多次,需要进行可持久化操作。
对于第二个问题,考虑合并的关系构成一个 ,每次合并会新建一个 节点, 操作的答案就是当前节点在 反图上可达的节点数目。
容易发现在反图上用线段树合并维护可达点集的复杂度分析与正向的合并相同,而查询当前时刻的节点数量,可以改为查询编号 的节点数量,其中 表示在查询时的编号最大的 节点。
只需要进行正反两次可持久化线段树合并,复杂度为 。
bool Mbe;
const int N=1.2e5+10,M=N*40,INF=1e9+10;
int n,m;
int rt[N*2],ls[M],rs[M],s[M],cnt;
void Ins(int &p,int l,int r,int x){
p=++cnt,s[p]=1;
if(l==r) return;
int mid=(l+r)>>1;
x<=mid?Ins(ls[p],l,mid,x):Ins(rs[p],mid+1,r,x);
}
int Union(int x,int y) {
if(!x || !y) return x|y;
int u=++cnt;
ls[u]=Union(ls[x],ls[y]);
rs[u]=Union(rs[x],rs[y]);
s[u]=s[x]+s[y];
return u;
}
int Que(int p,int l,int r,int x){
if(!p) return 0;
if(l==r) return 1;
int mid=(l+r)>>1;
return x<=mid?Que(ls[p],l,mid,x):Que(rs[p],mid+1,r,x);
}
int Que(int p,int l,int r,int ql,int qr) {
if(!p || ql>qr) return 0;
if(ql<=l && r<=qr) return s[p];
int mid=(l+r)>>1,res=0;
if(ql<=mid) res+=Que(ls[p],l,mid,ql,qr);
if(qr>mid) res+=Que(rs[p],mid+1,r,ql,qr);
return res;
}
char op[3];
int I[N],J[N];
vector <int> G[N*2];
int QX[N],QY[N];
bool Med;
int main() {
n=rd(),m=rd()+n-1;
rep(i,1,n) Ins(rt[i],1,n,i),J[i]=i;
int c=0,t=n;
rep(i,1,m) {
scanf("%s",op);
if(*op=='S') {
int a=rd(),b=rd();
++t;
if(!I[a]) I[a]=t;
else G[J[a]].pb(t);
if(!I[b]) I[b]=t;
else G[J[b]].pb(t);
rt[t]=Union(rt[J[a]],rt[J[b]]);
J[a]=J[b]=t;
} else if(*op=='Q') {
int a=J[rd()],b=rd();
QX[++c]=-Que(rt[a],1,n,b);
} else {
QX[++c]=rd(),QY[c]=t;
}
}
rep(i,1,::cnt) ls[i]=rs[i]=s[i]=0;
cnt=0;
drep(i,n*2-1,n+1) {
int u=i-n;
Ins(rt[u],1,n,u);
for(int j:G[i]) {
int v=j-n;
rt[u]=Union(rt[u],rt[v]);
}
}
rep(i,1,c) {
if(QX[i]<=0) puts(QX[i]?"yes":"no");
else printf("%d\n",Que(rt[I[QX[i]]-n],1,n,1,QY[i]-n)+1);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通