luogu P5443 [APIO2019]桥梁
题面传送门
这种东西显然不太好做。
所以考虑使用万能的分块。
对询问分块,每\(k\)个一块,然后我们发现,对于每个块中只有\(\frac{n}{k}\)条边被修改,所以可以暴力加入并查集。
然后对于每个块将询问和不被修改的边都按边权排序然后尺取出相应的边计入并查集即可。算完联通块大小以后要回退。
\(k\)取\(\sqrt{nlogn}\)最优。
但是常数使你并不很容易过掉。
我是把可撤销并查集换成了两个并查集,少了一个log,复杂度是\(O(n\sqrt nα(n))\)
code:
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 100039
#define I inline
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,k,id[N],q,x[N],y[N],op[N],r,lasttop,flag[N],head,ans[N],fl[N],fr,en;
struct ques{int x,y,z,id;}g[N];
struct yyy{int x,y,id;}f[N];
I bool cmps(yyy x,yyy y){return x.y>y.y;}
I bool cmp(ques x,ques y){return x.z<y.z;}
struct dsu{
int fa[N],siz[N],un,wn,gf[N],si[N],st[N],sh;
I int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
I int finds(int x){return x==gf[x]?x:gf[x]=finds(gf[x]);}
I void clear(){for(int i=1;i<=n;i++) fa[i]=gf[i]=i,siz[i]=si[i]=1;}
I void merge(int x,int y){un=find(x);wn=find(y);(un^wn)&&(siz[wn]+=siz[un],si[wn]+=si[un],fa[un]=wn);}
I void mere(int x,int y){un=finds(find(x));wn=finds(find(y));(un^wn)&&(un==find(x)&&(st[++sh]=un),wn==find(y)&&(st[++sh]=wn),si[wn]+=si[un],gf[un]=wn);}
I void pop(){while(sh) un=st[sh--],gf[un]=un,si[un]=siz[un];}
I int fz(int x){return si[finds(find(x))];}
}s;
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
register int i,j,h;scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].z),g[i].id=i;scanf("%d",&q);
for(i=1;i<=q;i++)scanf("%d%d%d",&op[i],&x[i],&y[i]);k=sqrt(q*log2(q));
for(i=0;i<=q/k;i++){
sort(g+1,g+m+1,cmp);for(j=1;j<=m;j++) id[g[j].id]=j;r=m;s.clear();fr=max(i*k,1);en=min(i*k+k-1,q);
for(j=fr;j<=en;j++)if(op[j]^2)flag[x[j]]=1;head=0;
for(j=fr;j<=en;j++)if(op[j]^1) f[++head]=(yyy){x[j],y[j],j};sort(f+1,f+head+1,cmps);
for(j=1;j<=head;j++){
while(r&&g[r].z>=f[j].y) !flag[g[r].id]&&(s.merge(g[r].x,g[r].y),0),r--;
for(h=f[j].id-1;h>=fr;h--) (op[h]^2)&&((!fl[x[h]])&&(y[h]>=f[j].y)&&(s.mere(g[id[x[h]]].x,g[id[x[h]]].y),0),fl[x[h]]=1);
for(h=f[j].id+1;h<=en;h++) (op[h]^2)&&(!fl[x[h]])&&(g[id[x[h]]].z>=f[j].y)&&(s.mere(g[id[x[h]]].x,g[id[x[h]]].y),0);
for(h=fr;h<f[j].id;h++) fl[x[h]]=0;ans[f[j].id]=s.fz(f[j].x);s.pop();
}
for(j=fr;j<=en;j++)(op[j]^2)?(g[id[x[j]]].z=y[j],flag[x[j]]=0):(printf("%d\n",ans[j]));
}
}