题解:P9598 [JOI Open 2018] 山体滑坡
forest114514 · · 题解
P9598 [JOI Open 2018] 山体滑坡
给一个认为
一句话,多次删边和加边,问你
没有修改考虑按
我们
新加边还要撤回操作的话使用可撤销并查集多一个
不过都不是很牛,我们想一想怎么优化?
我们考虑在
代码:
const int N=1e5+100,B=350;
int n,c,q,x[N],y[N],e[N],op[N],ans[N],fa[N],ff[N],tot,cnt,cnt2,ct;
LL hs[N];
int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);}
int getf2(int x){return x==ff[x]?x:ff[x]=getf2(ff[x]);}
vector<pii> que[N],opt[N];
vector<int> E[N];
bool vis[N],fl[N];
void merge(int x,int y){
x=getf(x),y=getf(y);
if(x==y) return;
++cnt,fa[x]=y;
}
void add(int x,int y){
x=getf(x),y=getf(y);
if(x==y) return;
x=getf2(x),y=getf2(y);
if(x==y) return;
ff[x]=y,++cnt2;
}
void del(int x,int y){
x=getf(x),y=getf(y);
ff[x]=x,ff[y]=y;
}
//bool _ED;
signed main(){
//fprintf(stderr,"%.20lf MB\n",(&_ST-&_ED)/1048576.0);
//ios::sync_with_stdio(false);
//cin.tie(0);cout.tie(0);
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
read(n,c,q);
rep(i,1,c) {
read(op[i],x[i],y[i]);
++x[i],++y[i];
if(x[i]>y[i]) swap(x[i],y[i]);
hs[i]=1ll*x[i]*n+y[i];
}
sort(hs+1,hs+1+c);
ct=unique(hs+1,hs+1+c)-hs-1;
rep(i,1,c) e[i]=lower_bound(hs+1,hs+1+ct,1ll*x[i]*n+y[i])-hs;
rep(i,1,q){
int t,x;
read(t,x);
++t,++x;
que[t].pb({x,i});
}
tot=(c+B-1)/B;
int l=0,r=0;
rep(T,1,tot){
l=r+1,r=min(l+B-1,c);
rep(i,l,r) fl[e[i]]=1;
rep(i,1,n) opt[i].clear(),ff[i]=fa[i]=i,E[i].clear();
rep(i,l,r) for(auto j:que[i]) opt[j.fi].pb({i,j.sc});
rep(i,1,l-1) if(vis[e[i]]&&(!fl[e[i]])) E[y[i]].pb(x[i]);
cnt=0;
rep(u,1,n){
for(auto v:E[u]) merge(u,v);
for(auto j:opt[u]){
int t=j.fi,id=j.sc;
cnt2=0;
rep(i,l,t) vis[e[i]]^=1;
rep(i,l,r) if(vis[e[i]]&&y[i]<=u) add(x[i],y[i]);
ans[id]-=cnt+cnt2;
rep(i,l,r) del(x[i],y[i]);
rep(i,l,t) vis[e[i]]^=1;
}
}
rep(i,1,n) opt[i].clear(),ff[i]=fa[i]=i,E[i].clear();
rep(i,l,r) for(auto j:que[i]) opt[j.fi+1].pb({i,j.sc});
rep(i,1,l-1) if(vis[e[i]]&&(!fl[e[i]])) E[x[i]].pb(y[i]);
cnt=0;
per(u,n,1){
for(auto v:E[u]) merge(u,v);
for(auto j:opt[u]){
int t=j.fi,id=j.sc;
cnt2=0;
rep(i,l,t) vis[e[i]]^=1;
rep(i,l,r) if(vis[e[i]]&&x[i]>=u) add(x[i],y[i]);
ans[id]-=cnt+cnt2;
rep(i,l,r) del(x[i],y[i]);
rep(i,l,t) vis[e[i]]^=1;
}
}
rep(i,l,r) vis[e[i]]^=1,fl[e[i]]=0;
}
rep(i,1,q) write(n+ans[i],'\n');
//fprintf(stderr,"%.4lf s\n",1.0*clock()/CLOCKS_PER_SEC);
return 0;
}