Black and white
题意:计算出矩阵元素的值,规定在2*2的矩阵中有三个被涂黑,则第四个自动被涂黑。求涂黑完整个矩阵花费的最小值。
矩阵的值是由(i,j)决定的,而A()的值由前一个A()决定,每次递推
a=(a* a* b+a*c+d)%p;
本题思路真的巧妙,将每个格子的值看作路径权重,坐标i,j看作路径连接的两个点,本题化为:给你n*m条路径,求联通m+n个点的最小权值。
没有用排序的kruscal。。因为遍历的时候就是枚举,从小到大。
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define int long long
#define lowbit(x) x&-x
#define N 200005
typedef pair<int,int>pll;
using namespace std;
int f[100005];
int find(int x){
if(x==f[x]) return f[x];
else return f[x]=find(f[x]);
}
signed main()
{
vector<pll>e[100005];
int n,m,a,b,c,d,p; cin>>n>>m>>a>>b>>c>>d>>p;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a=(a*a*b+a*c+d)%p;
e[a].push_back({i,n+j});//存储边连接的两个点
}
}
for(int i=1;i<=n+m;i++) f[i]=i;
int ans=0,cnt=0;
for(int i=0;i<p;i++){//直接排序
for(int j=0;j<e[i].size();j++){
int u,v;
u=find(e[i][j].first),v=find(e[i][j].second);
if(u!=v)
{
f[u]=v;
cnt++;
ans+=i;
}
}
if(cnt==n+m-1) break;
}
cout<<ans<<endl;
}
Math
题意:给一个n,计算有多少对(x,y)在n的范围内,并且满足(x2+y2)%(x*y+1)==0
打表输出,不难发现(i,i3)的关系,但是其中出现了少数数对如下:
8 30
27 240
30 112
64 1020
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
//#define ll long long
#define lowbit(x) x&-x
#define N 200005
typedef __int128 ll;
typedef pair<int,int>pll;
using namespace std;
signed main()
{
vector<ll>v;
for(ll i=2;i<=1e6;i++){
ll y=i*i*i;
ll x=i;
ll k=i*i;
v.push_back(y);
while(y<=1e18){
ll xx=y;
y=k*y-x;
x=xx;
if(y<=1e18) v.push_back(y);
}
}
sort(v.begin(),v.end());
int T; cin>>T;
while(T--){
long long n; cin>>n;
cout<<upper_bound(v.begin(),v.end(),n)-v.begin()+1<<endl;
}
}
Counting Triangles
题意:给出一个n个顶点的无向图和计算边颜色的一段代码,求三条边颜色相同且依次递增的三角形个数。
如果反着来思考就很好理解了,总的三角形个数-有异边的三角形个数
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define ll long long
//#define lowbit(x) x&-x
//#define N 200005
//typedef __int128 ll;
//typedef pair<int,int>pll;
namespace GenHelper {
unsigned z1, z2, z3, z4, b, u;
unsigned get() {
b = ((z1 << 6) ^ z1) >> 13;
z1 = ((z1 & 4294967294U) << 18) ^ b;
b = ((z2 << 2) ^ z2) >> 27;
z2 = ((z2 & 4294967288U) << 2) ^ b;
b = ((z3 << 13) ^ z3) >> 21;
z3 = ((z3 & 4294967280U) << 7) ^ b;
b = ((z4 << 3) ^ z4) >> 12;
z4 = ((z4 & 4294967168U) << 13) ^ b;
return (z1 ^ z2 ^ z3 ^ z4);
}
bool read() {
while (!u) u = get();
bool res = u & 1;
u >>= 1;
return res;
}
void srand(int x) {
z1 = x;
z2 = (~x) ^ 0x233333333U;
z3 = x ^ 0x1234598766U;
z4 = (~x) + 51;
u = 0;
}
}
using namespace GenHelper;
bool edge[8005][8005];
signed main() {
int n, seed, ans = 0;
cin >> n >> seed;
srand(seed);
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
edge[j][i] = edge[i][j] = read();
if (n < 3) cout << 0 << endl;
else {
ll ans = 1ll * n * (n - 1) * (n - 2) / 6;
ll a, b;
ll num = 0;
for (int i = 0; i < n; i++) {
a = b = 0;
for (int j = 0; j < n; j++) {
if (i == j)continue;
if (edge[i][j])b++;
else a++;
}
num += a * b;
}
cout << ans - num / 2 << endl;
}
}