大佬竟然可以用最小生成树做,我是没想到,,写个笔记记录下来。。虽然程序可能求不出最优解,,但是可以求出最优值也是不错了。。
AC代码:
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 3e7+10;
const int M = 10100;
int n,m,a,b,c,d,p;
int f[M];
struct node{
int i,j;
ll a;
bool operator < (const node& b) const {
return a < b.a;
}
}A[N];
void init(){
for(int i = 1;i<=n+m;i++) f[i] = i; //1-n表示行,n+1 - n+m表示列
A[0].a = a;
for(int i = 1;i<=n;i++)
for(int j = 1;j<=m;j++){
int id = m * (i-1)+j;
A[id] = {i,j,((ll)A[id-1].a*A[id-1].a * b + A[id-1].a*c + d) % p};
}
sort(A+1,A+n*m+1);
}
int find(int x){
return (f[x] == x ? x : (f[x] = find(f[x])));
}
void kruskal(){
ll ans = 0;
int cnt = n+m-1;
for(int i = 1;i<=n*m;i++){
int x = find(A[i].i),y = find(A[i].j + n);
ll v = A[i].a;
if(!cnt) break;
if(x!=y){
f[x] = y;
ans += v;
cnt--;
}
}
cout << ans << endl;
}
int main(){
scanf("%d%d%d%d%d%d%d",&n,&m,&a,&b,&c,&d,&p);
init();
kruskal();
return 0;
}