B-Black and white
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e7 + 10;
const int M = 5010;
struct node {
int x, y;
ll v;
bool operator<(const node& u) const { return v < u.v; }
} A[N];
int fa[2 * M];
int n, m, a, b, c, d, p;
void Init() {
A[0].v = 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].v * A[id - 1].v * b + (ll)A[id - 1].v * c + d) %
p};
}
}
int find(int x) {
if (x == fa[x])
return x;
return fa[x] = find(fa[x]);
}
void kruskal() {
//选若干个点(最少n+m-1个),使得所有行,所有列在一个联通块里面
ll res = 0, cnt = n + m - 1;
for (int i = 1; i <= n + m; i++)
fa[i] = i; // 1~n 表示行,n+1~n+m 表示列
sort(A + 1, A + 1 + m * n);
for (int i = 1; i <= m * n; i++) {
int x = A[i].x, y = A[i].y, v = A[i].v;
x = find(x), y = find(n + y);
if (!cnt)
break;
// 按理说 没有 cnt 这个变量 应该也可以,但是去掉后 只能过90% 剩下的10%
// 会 T,不知道为啥
if (x != y) {
fa[x] = y;
res += v;
cnt--;
}
}
cout << res << endl;
}
int main() {
cin >> n >> m >> a >> b >> c >> d >> p;
Init();
kruskal();
return 0;
}
题解:所以该题使用 Kruskal 求最小(花费)生成树,题解链接
E-Math
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN=1e18;
int T;
ll n,m=0,v[5000010];
int main()
{
v[m++]=1;
for(ll i=2;i*i*i<=MAXN;i++)
{
ll x=i,y=i*i*i;
v[m++]=y;
while(y<=(MAXN+x)/i/i)
{
x=i*i*y-x;
swap(x,y);
v[m++]=y;
}
}
sort(v,v+m);//从小到大进行排序方便二分找答案
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
printf("%lld\n",upper_bound(v,v+m,n)-v);
//二分找到的下标即是需要输出的正整数对的数量
}
}
题解:题解链接