[Codeforces] number theory (R1200) Part.5

[Codeforces] number theory (R1200) Part.5

题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200

1068B. LCM

原题指路:https://codeforces.com/problemset/problem/1068/B

题意

给定一个整数 b    ( 1 ≤ b ≤ 1 e 10 ) b\ \ (1\leq b\leq 1\mathrm{e}10) b  (1b1e10).对每个 a ∈ [ 1 , 1 e 18 ] a\in[1,1\mathrm{e}18] a[1,1e18],求 l c m ( a , b ) a \dfrac{\mathrm{lcm}(a,b)}{a} alcm(a,b)中有多少个相异的数.

思路

因原式中分子分母都含变量 a a a,考虑将一个变为常数 b b b.注意到 l c m ( a , b ) a = b gcd ⁡ ( a , b ) \dfrac{\mathrm{lcm}(a,b)}{a}=\dfrac{b}{\gcd(a,b)} alcm(a,b)=gcd(a,b)b,则相异的数的个数即 b b b的不同的约数的个数,试除法求即可,时间复杂度 O ( b ) O(\sqrt{b}) O(b ).

代码

void solve() {
	ll b; cin >> b;

	int ans = 0;
	for (int i = 1; i <= b / i; i++) 
		if (b % i == 0) ans += 1 + (i != b / i);
	cout << ans;
}

int main() {
	solve();
}


1076B. Divisor Subtraction

原题指路:https://codeforces.com/problemset/problem/1076/B

题意 ( 2   s 2\ \mathrm{s} 2 s)

给定一个整数 n    ( 2 ≤ n ≤ 1 e 10 ) n\ \ (2\leq n\leq 1\mathrm{e}10) n  (2n1e10),进行如下操作:

①若 n = 0 n=0 n=0,操作结束.

n n n减去其最小素因子,执行步骤①.

求减法的进行次数.

思路

①若 n n n是偶数,则其最小素因子为 2 2 2,显然 a n s = 2 n ans=\dfrac{2}{n} ans=n2.

②若 n n n是奇数,则它的最小素因子 d d d是奇数,减去一次后 n n n变为偶数,转化为情况①,故 a n s = 1 + n − d 2 ans=1+\dfrac{n-d}{2} ans=1+2nd.

代码

ll get(ll x) {  // 求x的最小素因子
	for (ll i = 2; i <= x / i; i++)
		if (x % i == 0) return i;
	return x;
}

void solve() {
	ll n; cin >> n;
	cout << (n & 1 ? 1 + (n - get(n)) / 2 : n / 2);
}

int main() {
	solve();
}


1107B. Digital root

原题指路:https://codeforces.com/problemset/problem/1107/B

题意

对一个非负整数,定义其digital root为一直求其各数位的和直至得到一个一位数.记数 x x x的digital root为 S ( x ) S(x) S(x),则 S ( 5 ) = 5 , S ( 38 ) = S ( 3 + 8 = 11 ) = S ( 1 + 1 = 2 ) = 2 , S ( 10 ) = S ( 1 + 0 = 1 ) = 1 S(5)=5,S(38)=S(3+8=11)=S(1+1=2)=2,S(10)=S(1+0=1)=1 S(5)=5,S(38)=S(3+8=11)=S(1+1=2)=2,S(10)=S(1+0=1)=1.

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入两个整数 k , x    ( 1 ≤ k ≤ 1 e 12 , 1 ≤ x ≤ 9 ) k,x\ \ (1\leq k\leq 1\mathrm{e}12,1\leq x\leq 9) k,x  (1k1e12,1x9),求第 k k k个digital root为 x x x的正整数.

思路

注意到 a k a k − 1 ⋯ a 1 ‾ = a 1 + a 2 ⋅ 10 + a 3 ⋅ 1 0 2 + ⋯ + a k ⋅ 1 0 k − 1 \overline{a_ka_{k-1}\cdots a_1}=a_1+a_2\cdot 10+a_3\cdot 10^2+\cdots+a_k\cdot 10^{k-1} akak1a1=a1+a210+a3102++ak10k1,而 1 0 a   m o d   9 = 1 10^a\ \mathrm{mod}\ 9=1 10a mod 9=1,则 a k a k − 1 ⋯ a 1 ‾ ≡ a 1 + a 2 + ⋯ + a k    ( m o d   9 ) \overline{a_ka_{k-1}\cdots a_1}\equiv a_1+a_2+\cdots+a_k\ \ (\mathrm{mod}\ 9) akak1a1a1+a2++ak  (mod 9),而digital root的定义是重复若干次该操作直至得到一个一位数,则数 x x x的digital root即 ( x − 1 )   m o d   9 + 1 (x-1)\ \mathrm{mod}\ 9+1 (x1) mod 9+1,故 a n s = 9 ( k − 1 ) + x ans=9(k-1)+x ans=9(k1)+x.

代码

void solve() {
	ll k; int x; cin >> k >> x;
	cout << (k - 1) * 9 + x << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


1108B. Divisors of Two Integers

原题指路:https://codeforces.com/problemset/problem/1108/B

题意

将两个正整数 x , y x,y x,y的所有因数组成一个列表,若某数同为 x x x y y y的因数,则它在列表中出现两次.

给定一个长度为 n    ( 2 ≤ n ≤ 128 ) n\ \ (2\leq n\leq 128) n  (2n128)的打乱的列表 d 1 , ⋯   , d n    ( 1 ≤ d i ≤ 1 e 4 ) d_1,\cdots,d_n\ \ (1\leq d_i\leq 1\mathrm{e}4) d1,,dn  (1di1e4).求该列表对应的 x x x y y y.数据保证有解.

思路

显然列表中的最大数是答案之一,将其的所有因数删去后,剩下的数中的最大值即答案之二.

代码

void solve() {
	int n; cin >> n;

	multiset<int> s;
	for (int i = 0; i < n; i++) {
		int x; cin >> x;
		s.insert(x);
	}

	int ans = *prev(s.end());
	for (int i = 1; i <= ans; i++) 
		if (ans % i == 0) s.erase(s.find(i));
	
	cout << ans << ' ' << *prev(s.end());
}

int main() {
	solve();
}


1133B. Preparation for International Women’s Day

原题指路:https://codeforces.com/problemset/problem/1133/B

题意 ( 2   s 2\ \mathrm{s} 2 s)

给定 n    ( 1 ≤ n ≤ 2 e 5 ) n\ \ (1\leq n\leq 2\mathrm{e}5) n  (1n2e5)个数 d 1 , ⋯   , d n    ( 1 ≤ d i ≤ 1 e 9 ) d_1,\cdots,d_n\ \ (1\leq d_i\leq 1\mathrm{e}9) d1,,dn  (1di1e9),问从中至多能选出多少个数(偶数个),将它们分成若干个数对后每个数对的数之和都能整除 k    ( 1 ≤ k ≤ 100 ) k\ \ (1\leq k\leq 100) k  (1k100).

思路

显然只需将数按模 k k k的余数分类即可.注意单独计算余数为 0 0 0的情况和 k k k为偶数时余数为 k 2 \dfrac{k}{2} 2k的情况.

代码

void solve() {
	int n, k; cin >> n >> k;

	vi cnt(k);  // cnt[i]表示模k余数为i的数的个数
	while (n--) {
		int x; cin >> x;
		cnt[x % k]++;
	}

	int ans = cnt[0] / 2;
	if (k % 2 == 0) ans += cnt[k / 2] / 2;
	for (int i = 1; i < (k + 1) / 2; i++) ans += min(cnt[i], cnt[k - i]);
	cout << ans * 2;
}

int main() {
	solve();
}


1143B. Nirvana

原题指路:https://codeforces.com/problemset/problem/1143/B

题意

给定一个整数 n    ( 1 ≤ n ≤ 2 e 9 ) n\ \ (1\leq n\leq 2\mathrm{e}9) n  (1n2e9),求 [ 1 , n ] [1,n] [1,n]中的整数中每个数位之积的最大值.

思路

显然应让数的结尾有尽量多的 9 9 9,即若 n = a 0 a 1 ⋯ a l ‾ n=\overline{a_0a_1\cdots a_l} n=a0a1al,则取得数位之积的最大值的数有形式 a 0 a 1 ⋯ a k ( a k + 1 − 1 ) 9 ⋯ 9 ‾ \overline{a_0a_1\cdots a_k(a_{k+1}-1)9\cdots 9} a0a1ak(ak+11)99,枚举分界点,分别求答案后取 max ⁡ \max max即可.

代码

int get_num(string s) {  // 字符串转数字
	int res = 0;
	for (auto ch : s) res = res * 10 + (ch & 15);
	return res;
}

int get_product(int x) {  // 求数位之积
	string s = to_string(x);
	int res = 1;
	for (auto ch : s) res *= ch & 15;
	return res;
}

void solve() {
	int n; cin >> n;

	string s = to_string(n);
	int ans = n;
	for (int i = 0; i < s.size(); i++) {  // 枚举分界点
		if (s[i] == '0') continue;

		string cur = s;
		cur[i]--;
		for (int j = i + 1; j < s.size(); j++) cur[j] = '9';
		int num = get_num(cur);

		if (num >= 1 && get_product(ans) < get_product(num)) ans = num;
	}
	cout << get_product(ans);
}

int main() {
	solve();
}


1149A. Prefix Sum Primes

原题指路:https://codeforces.com/problemset/problem/1149/A

题意

给定一个长度为 n    ( 1 ≤ n ≤ 2 e 5 ) n\ \ (1\leq n\leq 2\mathrm{e}5) n  (1n2e5)的序列 a 1 , ⋯   , a n    ( a i ∈ { 1 , 2 } ) a_1,\cdots,a_n\ \ (a_i\in\{1,2\}) a1,,an  (ai{1,2}),求一个排列使得其前缀和数组中素数的个数最多,输出任一符合的排列.

思路

因除 2 2 2外的素数都是奇数,故若初始序列非全 1 1 1或全 2 2 2,则可以 2 , 1 2,1 2,1开始,先放完剩下的 2 2 2,再放完剩下的 1 1 1,显然这是最优的.

代码

void solve() {
	int n; cin >> n;
	vi cnt(3);
	for (int i = 0; i < n; i++) {
		int a; cin >> a;
		cnt[a]++;
	}

	if (cnt[1] == n)
		for (int i = 0; i < n; i++) cout << 1 << ' ';
	else if (cnt[2] == n)
		for (int i = 0; i < n; i++) cout << 2 << ' ';
	else {
		cout << "2 1 ";
		cnt[2]--, cnt[1]--;
		while (cnt[2]--) cout << 2 << ' ';
		while (cnt[1]--) cout << 1 << ' ';
	}
}

int main() {
	solve();
}


1166B. All the Vowels Please

原题指路:https://codeforces.com/problemset/problem/1166/B

题意

给定一个整数 k    ( 1 ≤ k ≤ 1 e 4 ) k\ \ (1\leq k\leq 1\mathrm{e}4) k  (1k1e4),对长度为 k k k的单词,问能否将其每个字母依次从上到下逐行填入一个 n × m n\times m n×m矩阵,使得每行和每列中五个元音字母都至少出现一次,若有解,输出任一符合条件的单词;否则输出 − 1 -1 1.

思路

显然有解的充要条件是 n , m ≥ 5 n,m\geq 5 n,m5,且最优策略是只用五个元音字母,将它们依次填入.注意将 n , m n,m n,m中的较大者作为矩阵的行数.

代码

void solve() {
	int k; cin >> k;

	int n = -1, m = -1;
	for (int i = 5; i <= k / i; i++) {
		if (k % i == 0 && k / i >= 5) {
			n = i, m = k / i;
			break;
		}
	}

	if (n == -1 && m == -1) cout << -1;
	else {
		string pattern = "aeiou";
		string ans(k, ' ');
		for (int i = 0; i < m; i++)  // 先枚举大的
			for (int j = 0; j < n; j++) ans[i * n + j] = pattern[(i + j) % 5];
		cout << ans;
	}
}

int main() {
	solve();
}


1184A1. Heidi Learns Hashing (Easy)

原题指路:https://codeforces.com/problemset/problem/1184/A1

题意

给定一个整数 r    ( 1 ≤ r ≤ 1 e 12 ) r\ \ (1\leq r\leq 1\mathrm{e}12) r  (1r1e12),问是否存在一个正整数对 ( x , y )   s . t .   x 2 + 2 x y + x + 1 = r (x,y)\ s.t.\ x^2+2xy+x+1=r (x,y) s.t. x2+2xy+x+1=r,若存在,输出 x x x最小的一对;否则输出"NO".

思路I

注意到若有解,则 x ≤ r x\leq \sqrt{r} xr ,故枚举 x ∈ [ 1 , 1 e 6 ] x\in[1,1\mathrm{e}6] x[1,1e6],检查是否存在对应的 y y y即可.

代码I

void solve() {
	ll r; cin >> r;

	for (int x = 1; x <= 1e6; x++) {
		ll tmp = r - (ll)x * x - x - 1;
		if (tmp % (2 * x) || tmp / (2 *x) < 1) continue;

		cout << x << ' ' << tmp / (2 * x);
		return;
	}
	cout << "NO";
}

int main() {
	solve();
}

思路II

r = x 2 + 2 x y + x + 1 r=x^2+2xy+x+1 r=x2+2xy+x+1中,显然影响 r r r的奇偶性的只有 x 2 + x + 1 x^2+x+1 x2+x+1.注意到不管 x x x取奇数还是偶数, r r r都是奇数,故 r r r为偶数时无解.令 x = 1 x=1 x=1,解得 y = r − 3 2 y=\dfrac{r-3}{2} y=2r3,故 r ≥ 5 r\geq 5 r5时有解,且 x x x最小的解为 ( 1 , r − 3 2 ) \left(1,\dfrac{r-3}{2}\right) (1,2r3).

代码II

void solve() {
	ll r; cin >> r;

	if (r < 5 || r % 2 == 0) cout << "NO";
	else cout << 1 << ' ' << (r - 3) / 2;
}

int main() {
	solve();
}


1238A. Prime Subtraction

原题指路:https://codeforces.com/problemset/problem/1238/A

题意 ( 2   s 2\ \mathrm{s} 2 s)

给定两整数 x , y x,y x,y.现有操作:令 x x x减去一个素数 p p p.问若干次操作后能否将 x x x变为 y y y,若能则输出"YES";否则输出"NO".

t    ( 1 ≤ t ≤ 1000 ) t\ \ (1\leq t\leq 1000) t  (1t1000)组测试数据.每组测试数据输入两个整数 x , y    ( 1 ≤ y < x ≤ 1 e 18 ) x,y\ \ (1\leq y<x\leq 1\mathrm{e}18) x,y  (1y<x1e18).

思路

d = x − y d=x-y d=xy.

①若 d = 1 d=1 d=1,显然无法操作.

②若 d d d是偶数,即 x x x y y y奇偶时,可通过减若干次素数 2 2 2 x x x变为 y y y.,

③若 d d d是奇数且 d ≥ 3 d\geq 3 d3,即 x x x y y y不同奇偶时,可先减一次素数 3 3 3,再减若干次素数 2 2 2 x x x变为 y y y.

代码

void solve() {
	ll x, y; cin >> x >> y;
	cout << (x - y == 1 ? "NO" : "YES") << endl;
}

int main() {
	CaseT  // 单测时注释掉该行
	solve();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,Codeforces Round 511 (Div. 1)是一个比赛的名称。然而,引用内容中没有提供与这个比赛相关的具体信息或问题。因此,我无法回答关于Codeforces Round 511 (Div. 1)的问题。如果您有关于这个比赛的具体问题,请提供更多的信息,我将尽力回答。 #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces Round 867 (Div. 3)(A题到E题)](https://blog.csdn.net/wdgkd/article/details/130370975)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值