牛客2021暑期多校训练营3

原题链接

2021牛客暑期多校训练营3

B.Black and white

时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048576K 64bit IO Format: %lld

题目描述

Goodeat has a white chessboard with n rows and m columns.
Each grid (i,j) has a weight c(i,j). At any time, the grid (i,j) can be dyed black at the cost of c(i,j).
Goodeat has a special talent. For the four intersecting squares of any two rows and two columns, if three of them are black squares, Goodeat can dye the fourth square black without any cost.
Please find out the minimum cost of dyeing a black chessboard.
Due to the large number of grids, we use the following method to generate weights:
A0=a
A(i+1)=(AiAib+Aic+d)
Where A(m(i1)+j) is the cost c(i,j) of the grid in the ith row and jth column (1in,1jm).

输入描述:

The first line contains seven integers n,m,a,b,c,d,p.(a,b,c,d<p100000,n,m5000)

输出描述:

Output a single integer denoting the answer.

输入

4 4 1 2 3 4 7

输出

20

说明

Here is the weight matrix:

2 4 6 3 3 3 3 3 3 3 3 3 3 3 3 3

解题思路

最小生成树

EOJ Monthly 2021.9——C. Connection类似的思路
开始时都是白棋,每行每列都不连通,目的是使花费最小,倘若一开始便联通,则不用花费,所以目的是使其联通并且代价最小,所以就是求行、列构成点的最小生成树~
注意:本题是稠密图,应使用prim算法

  • 时间复杂度:O(n2)

代码

#include<bits/stdc++.h> using namespace std; const int N=5005; int adj[N*2][N*2]; int n,m,a,b,c,d,p; int dis[N*2]; bool v[N*2]; void prim() { memset(dis,0x3f,sizeof dis); dis[1]=0; for(int i=1;i<n+m;i++) { int x=0; for(int j=1;j<=n+m;j++) if(!v[j]&&(x==0||dis[j]<dis[x]))x=j; v[x]=1; for(int y=1;y<=n+m;y++) if(!v[y]) dis[y]=min(dis[y],adj[x][y]); } } int main() { scanf("%d%d%d%d%d%d%d",&n,&m,&a,&b,&c,&d,&p); int A=a; memset(adj,0x3f,sizeof adj); for(int i=1;i<=n+m;i++)adj[i][i]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { A=(1ll*A*A*b%p+1ll*A*c+d)%p; adj[i][n+j]=adj[n+j][i]=min(adj[i][n+j],A); } } //prim算法求最小生成树 prim(); int res=0; for(int i=2;i<=n+m;i++)res+=dis[i]; printf("%d",res); return 0; }

J.Counting Triangles

时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld

题目描述

Goodeat finds an undirected complete graph with n vertices. Each edge of the graph is painted black or white. He wants you to help him find the number of triangles (a, b, c) (a < b < c), such that the edges between (a, b), (b, c), (c, a) have the same color. To avoid the input scale being too large, we use the following code to generate edges in the graph.

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]; int main() { int n, seed; 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(); return 0; }

The edge array in the above code stores the color of the edges in the graph. edge[i][j]=1 means that the edge from i to j is black, otherwise it is white (0ijn1).
Ensure that there is an approach that does not depend on the way the data is generated.

输入描述:

The first line contains two integers n(n8000),seed(seed109), denote the number of vertices and the seed of random generator.

输出描述:

Output a line denoting the answer.

输入

10 114514

输出

35

说明

There're 35 triangles that all three edges have the same color.

解题思路

容斥原理

原问题不好直接求解,我们不妨考虑其反面,即:异色三角形
我们只需要找出这样的点的数量:其两边异色,找出所有这样的点的数量 cnt 后,cnt÷2 即异色三角形的个数,用总个数 Cn3 减去即可~

cnt÷2
我们求得的 cnt 是异色角的个数,而一个异色三角形由两个异色角和一个同色角构成,每个点枚举的时候都会重复枚举一次
注意:可能会超int

  • 时间复杂度:O(n2)

代码

#include<bits/stdc++.h> using namespace std; using LL=long long; 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]; int main() { int n, seed; 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(); LL diff=0; for(int i=0;i<n;i++) { LL s[2]={0,0}; for(int j=0;j<n;j++) { if(i==j)continue; s[edge[i][j]]++; } diff+=s[0]*s[1]/2; } cout<<1ll*n*(n-1)*(n-2)/6-diff; return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15302292.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(59)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示