Codeforces Round #729 div.2 A-E题解

Posted 欣君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #729 div.2 A-E题解相关的知识,希望对你有一定的参考价值。

视频讲解:BV1hB4y1N7jF

A. Odd Set

题目大意

给定 2 n ( 1 ≤ n ≤ 100 ) 2n(1 \\leq n \\leq 100) 2n(1n100) 个可能重复的整数 a i ( 0 ≤ a i ≤ 100 ) a_i(0 \\leq a_i \\leq 100) ai(0ai100) ,问是否能将其分为 n n n 对,使得每对的两个整数之和为奇数。

题解

只有当每对内包含一个奇数加一个偶数时,才能使其总和为奇数。因此充要条件为奇数个数与偶数个数相等。

参考代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

int main()

	int T,n,x,i,sum0,sum1;
	scanf("%d",&T);
	while(T--)
	
		scanf("%d",&n);
		sum0=sum1=0;
		for(i=1;i<=2*n;i++)
		
			scanf("%d",&x);
			if(x&1)
				sum1++;
			else
				sum0++;
		
		if(sum1==sum0)
			printf("Yes\\n");
		else
			printf("No\\n");
	

B. Plus and Multiply

题目大意

有一个无限大的集合,定义如下:

  • 1 1 1 在集合中;
  • 如果 x x x 在集合中,则 x ⋅ a x \\cdot a xa x + b x+b x+b 也在集合中;

给定 n , a , b ( 1 ≤ n , a , b ≤ 1 0 9 ) n,a,b(1 \\leq n,a,b \\leq 10^9) n,a,b(1n,a,b109),判断 n n n 是否在集合中。

题解

如果 n n n 在集合中,那么 n n n 必定可以表达为:
n = a x + b ⋅ y n=a^x+b \\cdot y n=ax+by

其中 0 ≤ x , y 0 \\leq x,y 0x,y 。因此只要枚举 x x x ,判断是否存在合法的 y y y 即可。
注意, a a a 可能等于 1 1 1 ,因此需要特判,或限定枚举次数。

参考代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

int main()

	int T,i;
	ll n,a,b,base;
	bool flag;
	scanf("%lld",&T);
	while(T--)
	
		scanf("%lld%lld%lld",&n,&a,&b);
		base=1;
		flag=false;
		for(i=1;i<=30&&base<=n;i++,base*=a)
		
			if((n-base)%b==0)
			
				flag=true;
				break;
			
		
		if(flag)
			printf("Yes\\n");
		else
			printf("No\\n");
	

C. Strange Function

题目大意

f ( i ) f(i) f(i) 表示最小的不是 i i i 的因数的整数。
∑ i = 1 n f ( i ) \\sum_i=1^nf(i) i=1nf(i) 1 0 9 + 7 10^9+7 109+7 取模的结果。
其中 1 ≤ n ≤ 1 0 16 1 \\leq n \\leq 10^16 1n1016

题解

首先会发现, f ( i ) f(i) f(i) 应该是一个相比 i i i 而言,很小的数。
如果 f ( i ) = y f(i)=y f(i)=y ,那么 i i i 需要是 L C M ( 1 , 2 , . . . , ( y − 1 ) ) LCM(1,2,...,(y-1)) LCM(1,2,...,(y1)) 的倍数,这个类似于阶乘的条件十分苛刻。
a i = L C M ( 1 , 2 , 3 , . . . , i ) a_i=LCM(1,2,3,...,i) ai=LCM(1,2,3,...,i) ,可以通过递推打表的方式求出所有小于 1 0 16 10^16 1016 a i a_i ai
x x x a i a_i ai 的倍数,则有 f ( x ) ≥ i + 1 f(x) \\geq i+1 f(x)i+1
因此可以通过枚举 i i i ,统计有多少个不超过 n n n a i a_i ai 的倍数,从而累加到答案上。
具体而言,
a n s = ( n + ∑ i = 1 a i ≤ n ⌊ n a i ⌋ ) %    m o d ans=(n+\\sum_i=1^a_i \\leq n\\lfloor \\fracna_i \\rfloor) \\% \\;mod ans=(n+i=1ainain)%mod

时间复杂度 O ( T ⋅ log ⁡ ( n ) ) O(T \\cdot \\log(n)) O(Tlog(n))

参考代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

const ll MAXN=1e16+100;
const ll mod=1e9+7;
ll a[50];

int main()

	int T,cnt,i;
	ll n,ans;
	a[0]=a[1]=1;
	for(cnt=1;a[cnt-1]<MAXN;cnt++)
	
		for(i=1;i<=cnt;i++)
		
			if(a[cnt-1]*i%cnt==0)
			
				a[cnt]=a[cnt-1]*i;
				break;
			
		
	
	scanf("%d",&T);
	while(T--)
	
		scanf("%lld",&n);
		ans=0;
		for(i=0;i<cnt&&a[i]<=n;i++)
			ans=(ans+n/a[i])%mod;
		printf("%lld\\n",ans);
	

D. Priority Queue

题目大意

对于由 + x +x +x − - 构成的操作序列 S S S ,定义函数 f ( S ) f(S) f(S) 由以下方式计算得到:

  • 从左到右遍历 S S S ,并维护一个多重集合 T T T
  • 对于 S S S 中的每个元素,若其为 + x +x +x ,则添加 x x x T T T 中;否则删除 T T T 中最小的元素(若 T T T 为空,则不进行任何操作);
  • 遍历完 S S S 中的所有元素后,求 T T T 中所有元素的总和,就是 f ( S ) f(S) f(S) ;

给定一个长度为 n ( 1 ≤ n ≤ 500 ) n(1 \\leq n \\leq 500) n(1n500) 的操作序列 A A A ,求 A A A 的所有子序列 B B B f ( B ) f(B) 以上是关于Codeforces Round #729 div.2 A-E题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #729 (Div. 2)

Codeforces Round #729 div.2 A-E题解

Codeforces Round #729 div.2 A-E题解

Codeforces Round #729 (Div. 2) C(数学)

Codeforces Round #729 (Div. 2) D. Priority Queue(简单dp)

Codeforces Round #729 (Div. 2) C. Strange Function