Codeforces Round #729 div.2 A-E题解
Posted 欣君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #729 div.2 A-E题解相关的知识,希望对你有一定的参考价值。
视频讲解:TBD
A. Odd Set
题目大意
给定 2 n ( 1 ≤ n ≤ 100 ) 2n(1 \\leq n \\leq 100) 2n(1≤n≤100) 个可能重复的整数 a i ( 0 ≤ a i ≤ 100 ) a_i(0 \\leq a_i \\leq 100) ai(0≤ai≤100) ,问是否能将其分为 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 x⋅a 和 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(1≤n,a,b≤109),判断 n n n 是否在集合中。
题解
如果
n
n
n 在集合中,那么
n
n
n 必定可以表达为:
n
=
a
x
+
b
⋅
y
n=a^x+b \\cdot y
n=ax+b⋅y
其中
0
≤
x
,
y
0 \\leq x,y
0≤x,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}^n{f(i)}
∑i=1nf(i) 对
1
0
9
+
7
10^9+7
109+7 取模的结果。
其中
1
≤
n
≤
1
0
16
1 \\leq n \\leq 10^{16}
1≤n≤1016 。
题解
首先会发现,
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,...,(y−1)) 的倍数,这个类似于阶乘的条件十分苛刻。
设
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 \\frac{n}{a_i} \\rfloor}) \\% \\;mod
ans=(n+i=1∑ai≤n⌊ain⌋)%mod
时间复杂度 O ( T ⋅ log ( n ) ) O(T \\cdot \\log(n)) O(T⋅log(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(1≤n≤500) 的操作序列 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(数学)