B-Black and white
效仿codeforces1012 B. Chemical table(并查集+思维),只不过边带权,是的n+m个点联通,显然就是求最小生成树。
Code1 Kruskal
O(n2logn2)O(n^2\log n^2)O(n2logn2)
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=400010;
int fa[N];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int n,m,b,c,d,p,cur;
int merge(int x,int y)
{if(find(x)==find(y)) return 0;fa[find(x)]=find(y);--cur;return 1;
}
struct node
{int u,v;int w;bool operator<(const node&o)const{return w<o.w;}
}e[25000010];
int a[25000010];
int main()
{n=rd(),m=rd(),a[0]=rd(),b=rd(),c=rd(),d=rd(),p=rd();int cnt=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cnt++;a[cnt]=(1ll*a[cnt-1]*a[cnt-1]%p*b%p+a[cnt-1]*c%p+d)%p;e[cnt]={i,j+n,a[cnt]};}sort(e+1,e+1+cnt);cur=n+m;for(int i=1;i<=n+m;i++) fa[i]=i;ll ans=0;for(int i=1;i<=cnt;i++){if(cur==1) break;if(merge(e[i].u,e[i].v)) ans+=e[i].w;}printf("%lld\n",ans);return 0;
}
Code2 prim
O(n2)O(n^2)O(n2)
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
int n,m,A,B,C,D,P;
int g[10010][10010];
int a[25000010];
int d[15010];
bool st[15010];
ll prim()
{memset(d,0x3f,sizeof d);ll ans=0;d[1]=0;for(int i=0;i<n+m;i++){int t=-1;for(int j=1;j<=n+m;j++)if(!st[j]&&(t==-1||d[j]<d[t])) t=j;if(d[t]==0x3f3f3f3f) return d[t];st[t]=1;ans+=d[t];for(int j=1;j<=n+m;j++)d[j]=min(d[j],g[t][j]);}return ans;
}
int main()
{n=rd(),m=rd(),A=rd(),B=rd(),C=rd(),D=rd(),P=rd();a[0]=A;memset(g,0x3f,sizeof g);for(int i=1;i<=n*m;i++){a[i]=(1ll*a[i-1]*a[i-1]%P*B%P+a[i-1]*C%P+D)%P;int u=(i-1)/m+1;int v=(i-1)%m+1;g[u][v+n]=g[v+n][u]=a[i];}printf("%lld\n",prim());return 0;
}