[做题记录] 构造题选做

1. CF743C - Vladik and fractions (*1500)

目标:给定 n,构造 x,y,z 满足 xy,xz,yz2n=1x+1y+1z

Hint:1n+1n+1+1n(n+1)=n+1+n+1n(n+1)=2(n+1)n(n+1)=2n

n=1 时会出现 x=1,y=2,z=2 的情况,无解。

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
signed main () {
	int n;
	scanf ("%d", &n);
	if (n == 1) printf ("-1\n");
	else printf ("%d %d %d\n", n, n + 1, n * (n + 1));
	return 0;
}

2. CF1758D - Range = √Sum (*1800)

目标:给定 n,求一个长度为 n 的数组 [a1,a2,,an],满足:1ai109,1inmaxi=1naimini=1nai=i=1nai

考虑奇偶分类。

nmod2=0 时,发现 [n2,n2+1,,n1,n+1,,3n2] 满足条件。

极差:3nn2=n

和:

3n2(3n2+1)2n2(n21)2n

9n24+3n22n24n22n

9n28+3n4n28+n4n

Sum=n2

所以满足条件。

nmod2=1 时,先构造一个以 n 为中心的公差为 1 的等差数列([n+52,n+72,,3n+32]),极差为 n1,和为 n2

将所有数加 2,可以让和变为 n2+2n,极差为 n1

发现极差需要增加 2,那就最小值减 1,最大值加 1 吧,现在极差为 n+1,和为 n2+2n,现在只需要将和加 1 了,那就将次大值加 1,保证还会小于最大值,所以不会影响极差,和为 n2+2n+1=(n+1)2

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
int _, n, a[300005];
signed main () {
	scanf ("%d", &_);
	while (_ --) {
		scanf ("%d", &n);
		if (n % 2 == 0) {
			for (int i = n / 2;i <= 3 * n / 2; ++ i) {
				if (i != n) printf ("%d ", i);
			}
			printf ("\n");
		}
		else {
			for (int i = 1;i <= n; ++ i) a[i] = i;
			int mid = n / 2 + 1;
			int delta = n - mid;
			for (int i = 1;i <= n; ++ i) a[i] += delta + 2;
			a[1] --, a[n] ++;
			a[n - 1] ++;
			for (int i = 1;i <= n; ++ i) printf ("%d ", a[i]);
			printf ("\n");
		}
	}
	return 0;
}

3. CF1734E - Rectangular Congruence (*2100)

目标:给定质数 n,求一个矩阵满足:

  • 对于所有的 1i,jn0ai,j<n

  • 对于所有的 1r1<r2n,1c1<c2n,有 (ar1,c1+ar2,c2)modn(ar1,c2+ar2,c1)modn

  • 对于所有的 1inai,i=bi

对第二个条件进行变形,有:(ar1,c1ar1,c2)modn=(ar2,c1ar2,c2)modn

所以对于一个合法的矩阵的同一行加上同一个数依然合法。

让第 i 行的差值为 i1 的倍数,可以构造出:

[00012n10(n1)(n1)×(n1)modn]

剩下的操作就是调整每一行使得它满足第三个条件。

第一个条件就是 modn

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif
typedef long long ll;
typedef pair < int, int > PII;
typedef int itn;
mt19937 RND_MAKER (chrono :: steady_clock :: now ().time_since_epoch ().count ());
inline ll randomly (const ll l, const ll r) {return (RND_MAKER () ^ (1ull << 63)) % (r - l + 1) + l;}
//#define int long long
const double pi = acos (-1);
//__gnu_pbds :: tree < Key, Mapped, Cmp_Fn = std :: less < Key >, Tag = rb_tree_tag, Node_Upadte = null_tree_node_update, Allocator = std :: allocator < char > > ;
//__gnu_pbds :: tree < PPS, __gnu_pbds :: null_type, less < PPS >, __gnu_pbds :: rb_tree_tag, __gnu_pbds :: tree_order_statistics_node_update > tr;
int a[355][355], n, b[355];
signed main () {
	scanf ("%d", &n);
	for (int i = 1;i <= n; ++ i) {
		for (int j = 1;j <= n; ++ j) {
			a[i][j] = (i - 1) * (j - 1) % n;
		}
	}
	for (int i = 1;i <= n; ++ i) {
		scanf ("%d", &b[i]);
		int delta = b[i] - a[i][i];
		for (int j = 1;j <= n; ++ j) a[i][j] += delta;
	}
	for (int i = 1;i <= n; ++ i) {
		for (int j = 1;j <= n; ++ j) {
			a[i][j] = (a[i][j] % n + n) % n;
			printf ("%d ", a[i][j]);
		}
		printf ("\n");
	}
	return 0;
}
posted @   CountingGroup  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示