[APIO2019] bridge

Topic Link
(luogu on this topic now very tight time frame, the code solution to a problem area is not necessarily too)

Meaning of the questions:

There are a n points, without edges to FIG. M, and the right side of each value; two operations:

1 a side of the modified weights.
2 inquiry from a certain point, only been to greater than a given weight of the edge, you can reach up to several points.

solution

First consider if there is no modification operations, how to do it:
apparently you can put down and ask offline, according to a given weight descending order, and then set the maintenance and check the answers.

If there does it work? We also extended the above ideas, with disjoint-set maintenance answer then is that every l o g ( n ) m \sqrt {log(n)*m} Operations into one, for query operations within the block, apparently have not been modified within the block edges will not be modified, so you can sort directly, maintain and operate with no modification of the method, and then for a query, violence traversal All modification operations, consider the time sequence modification operation, whether it is necessary to modify.
the operation then after a block is processed, all modifications to the processing operations, the value of the right side of the case has changed, reordering required.

note

I wrote this afternoon, mainly in the block has been modified operating details not solved: one side may be modified several times, only the most recent one is useful and if one edge before the query was. modified, then the query is modified, or can only be used before the inquiry (may not be well understood, you can look at the code).
then sort can not always direct violence row m edges, but ranked only be modified edge, then merge merge back when needed. so first side if the ordered (need to start a row order).

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
inline int read(){
	char c=getchar();int t=0,f=1;
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
	return t*f;
}
int n,m,Q;
struct node{
	int u,v,w,id;
	node(int a=0,int b=0,int c=0,int d=0){u=a,v=b,w=c,id=d;}
}e[maxn],e1[maxn],e2[maxn];
struct ak{
	int op,s,w,id;
	ak(int a=0,int b=0,int c=0,int d=0){op=a,s=b,w=c;id=d;}
}q[maxn],alfa[maxn],beta[maxn];
int cnt;
bool cmp(node a,node b){
	return a.w>b.w;
}
bool cmp2(ak a,ak b){
	return a.w>b.w;
}
int op[maxn],f[maxn];
inline int find(int x){
	return f[x]==x?f[x]:find(f[x]);
}
int cnt1,cnt2,top,sz[maxn],dep[maxn];
node st[maxn];
inline void merge(int u,int v){
	int x=find(u),y=find(v);
	if(dep[x]>dep[y])swap(x,y);
	if(x==y)return ;
	f[x]=y;sz[y]+=sz[x];if(dep[x]==dep[y])dep[y]++;
}
inline void merge2(int u,int v){
	int x=find(u),y=find(v);
	//printf("%d %d\n",x,y);
	if(sz[x]>sz[y])swap(x,y);
	if(x==y)return ;
	st[++top]=node(x,f[x],y,sz[x]);
	f[x]=y;sz[y]+=sz[x];if(dep[x]==dep[y])dep[y]++;
}
int g[maxn],ans[maxn],pos[maxn],vis[maxn];
void work(){
	cnt1=cnt2=0;
	for(int i=1;i<=n;i++){
		f[i]=i;sz[i]=1;dep[i]=1;
	}
	for(int i=1;i<=m;i++){
		g[i]=0;
	}
	for(int i=1;i<=cnt;i++){
		if(q[i].op==1){alfa[++cnt1]=q[i];g[q[i].s]=1;}
		else beta[++cnt2]=q[i];
	}
	for(int i=1;i<=m;i++)pos[e[i].id]=i;
	sort(beta+1,beta+1+cnt2,cmp2);
	int p=1;
	for(int i=1;i<=cnt2;i++){
		while(e[p].w>=beta[i].w&&p<=m){
			if(g[e[p].id]){
				p++;
			}
			else{
				//printf("%d %d %d\n",e[p].u,e[p].v,e[p].w);
				merge(e[p].u,e[p].v);p++;
			}
		}
		int flag=1;
		for(int j=1;j<=cnt1;j++){
			if(alfa[j].id>beta[i].id){
				for(int k=j-1;k>=1;k--){
					if(vis[pos[alfa[k].s]])continue;
					vis[pos[alfa[k].s]]=1;
					if(alfa[k].w>=beta[i].w){
						//printf("%d %d %d?\n",e[pos[alfa[k].s]].u,e[pos[alfa[k].s]].v,alfa[k].w);
						merge2(e[pos[alfa[k].s]].u,e[pos[alfa[k].s]].v);
					}
				}
				for(int k=j;k<=cnt1;k++){
					if(vis[pos[alfa[k].s]])continue;
					if(e[pos[alfa[k].s]].w>=beta[i].w){
						//printf("%d %d %d.\n",e[pos[alfa[k].s]].u,e[pos[alfa[k].s]].v,e[pos[alfa[k].s]].w);
						merge2(e[pos[alfa[k].s]].u,e[pos[alfa[k].s]].v);
					}
				}
				for(int k=1;k<=cnt1;k++)vis[pos[alfa[k].s]]=0;
				flag=0;
				break;
			}
		}
		if(flag){
			for(int k=cnt1;k>=1;k--){
				if(vis[pos[alfa[k].s]])continue;
				vis[pos[alfa[k].s]]=1;
				if(alfa[k].w>=beta[i].w){
					merge2(e[pos[alfa[k].s]].u,e[pos[alfa[k].s]].v);
				}
			}
			for(int k=1;k<=cnt1;k++)vis[pos[alfa[k].s]]=0;
		}
		ans[beta[i].id]=sz[find(beta[i].s)];
		//printf("%d %d!\n",beta[i].s,ans[beta[i].id]);
		while(top){
			int u=st[top].u,val=st[top].v,v=st[top].w;int flag=st[top].id;
			f[u]=val;sz[v]-=flag;sz[u]=flag;
			top--;
		}
	}
	for(int i=1;i<=cnt1;i++){
		e[pos[alfa[i].s]].w=alfa[i].w;
	}
	int tot1=0,tot2=0,tot3=0;
	for(int i=1;i<=m;i++){
		if(g[e[i].id])e2[++tot2]=e[i];
		else e1[++tot1]=e[i];
	}
	sort(e2+1,e2+1+tot2,cmp);
	int p1=1,p2=1;
	while(p1<=tot1&&p2<=tot2){
		if(e1[p1].w>e2[p2].w){tot3++;e[tot3]=e1[p1];p1++;}
		else {tot3++;e[tot3]=e2[p2];p2++;}
	}
	while(p1<=tot1){tot3++;e[tot3]=e1[p1],p1++;}
	while(p2<=tot2){tot3++;e[tot3]=e2[p2],p2++;}
}
int main(){
	//freopen("luogu5443.in","r",stdin);
	//freopen("luogu5443.out","w",stdout);
	n=read(),m=read();
	int lim=sqrt(m*log(n));
	//printf("%d\n",lim);
	for(int i=1;i<=m;i++){
		e[i].u=read(),e[i].v=read();e[i].w=read();e[i].id=i;
	}
	sort(e+1,e+1+m,cmp);
	Q=read();
	for(int i=1;i<=Q;i++){
		q[++cnt].op=read();q[cnt].s=read(),q[cnt].w=read();q[cnt].id=i;
		op[i]=q[cnt].op;
		if(cnt==lim){work();cnt=0;}
	}
	if(cnt)work();
	for(int i=1;i<=Q;i++){
		if(op[i]==2){
			printf("%d\n",ans[i]);
		}
	}
	return 0;
}

发布了62 篇原创文章 · 获赞 1 · 访问量 1000

Guess you like

Origin blog.csdn.net/wmhtxdy/article/details/103809717