海亮 7.19 模拟赛

海亮 7.19 模拟赛

赛时感冒咳嗽极重 最后一小时在摆另一道题

本来以为只能拿40+0+0+30=70pts的 但是拿了85+0+0+30=115pts?

T1不太会算复杂度/kk 上来冲正解不成功就打了个暴力跑路()

T4 30pts特判显然

有意义的一道题 成功让我抛弃了链前存图而改用vector

我们考虑类比三元环计数 先统计出来所有答案 再减去三元环的答案即可

e1存的是原图 e存的是三元组的图

buc[i]表示的是权值为i的点对个数 tmp[i]表示的是在当前节点的出点内 权值为i的儿子有多少个

这样就可以在遍历原图的时候统计答案了

因为三元环是不合法的 那么我们直接在新图中扫描所有三元环并减去贡献即可

统计max:最后的时候从大到小扫描权值

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define mid (l+r>>1)
#define int long long
const int N = 3e4 + 5;
const int inf = 0x3f3f3f3f3f3f3f3f;
int read ()
{
	int x = 0 , f = 1;
	char ch = cin.get();
	while ( !isdigit ( ch ) ) { if ( ch == '-' ) f = -1; ch = cin.get(); }
	while ( isdigit ( ch ) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = cin.get(); }
	return x * f;
}

int n , m , t , vis[N] , tmp[N] , u[N] , v[N] , a[N] , maxx = -1 , summ , buc[N] , maxval;

vector<int> e[N] , e1[N];

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	n = read() , m = read() , t = read();
	for ( int i = 1 ; i <= m ; i ++ ) u[i] = read() , v[i] = read() , e1[u[i]].push_back(v[i]) , e1[v[i]].push_back(u[i]);
	for ( int i = 1 ; i <= n ; i ++ ) a[i] = read() , maxval = max ( maxval , a[i] );
	for ( int i = 1 ; i <= m ; i ++ )
	{
		if ( e1[u[i]].size() > e1[v[i]].size() ) swap ( u[i] , v[i] );
		else if ( e1[u[i]].size() == e1[v[i]].size() && u[i] > v[i] ) swap ( u[i] , v[i] );
		e[u[i]].push_back(v[i]);
	}
	for ( int u = 1 ; u <= n ; u ++ )
	{
		int sum = 0;//出边到达的点的权值sum 
		for ( auto v : e1[u] )
		{
			summ += sum * a[v] , sum += a[v];
			for ( int i = 1 ; i <= maxval ; i ++ ) buc[i*a[v]] += tmp[i];
			tmp[a[v]] ++;
		}
		for ( auto v : e1[u] ) tmp[a[v]] = 0;
	}
	for ( int u = 1 ; u <= n ; u ++ )
	{
		for ( auto v : e[u] ) vis[v] = u;
		for ( auto v : e[u] ) for ( auto w : e[v] ) if ( vis[w] == u ) 
			buc[a[u]*a[v]] -- , buc[a[v]*a[w]] -- , buc[a[u]*a[w]] -- , summ -= a[u]*a[v] + a[u]*a[w] + a[v]*a[w];
	}//保证了每一个三元环只会被统计一次 
	for ( int i = maxval * maxval ; i ; i -- ) if ( buc[i] ) { maxx = i; break; }
	cout << ( ( t != 2 ) ? maxx : 0 ) << endl;
	cout << ( ( t != 1 ) ? ( summ << 1 ) : 0 ) << endl;
	return 0;
}

#D. 扫雷(landmine)

我们考虑先将5×5的方格中填满"八卦图" 再推广到整张图

也就是下面的东西:

0 0 0 1 0

0 1 0 0 0

0 0 0 0 1

0 0 1 0 0

1 0 0 0 0

然后我们在前5×5个方格枚举题目中要求的n×m矩阵的左上角 再暴力统计答案即可

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define mid (l+r>>1)
const int N = 500 + 5;
const int inf = 0x3f3f3f3f;
int read ()
{
	int x = 0 , f = 1;
	char ch = cin.get();
	while ( !isdigit ( ch ) ) { if ( ch == '-' ) f = -1; ch = cin.get(); }
	while ( isdigit ( ch ) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = cin.get(); }
	return x * f;
}

int n , m , f[N][N] , cnt;
int st[5] = { 5 , 2 , 4 , 1 , 3 };

int calc ( int x , int y , int xx , int yy )
{
	int res = 0;
	for ( int i = x ; i <= xx ; i ++ )
		for ( int j = y ; j <= yy ; j ++ )
			res += f[i][j];
	return res;
}

signed main ()
{
	ios::sync_with_stdio(false);
	cin.tie(0) , cout.tie(0);
	for ( int i = 1 ; i <= N ; i ++ )
		for ( int j = st[i%5] ; j <= N ; j += 5 )
			f[i][j] = 1;
	n = read() , m = read();
	int minn = inf , mini , minj;
	for ( int i = 1 ; i <= 5 ; i ++ )
		for ( int j = 1 ; j <= 5 ; j ++ )
			if ( calc ( i , j , i + n - 1 , j + m - 1 ) < minn ) minn = calc ( i , j , i + n - 1 , j + m - 1 ) , mini = i , minj = j;
	cout << minn << endl;
	for ( int i = mini ; i <= mini + n - 1 ; i ++ , cout.put(endl) )
		for ( int j = minj ; j <= minj + m - 1 ; j ++ )
			cout << f[i][j];
	return 0;
}
posted @   Echo_Long  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示