Codeforces Round #701 (Div. 2) Summary
A. Add and Divide:搜索+贪心
首先我没有想到什么好的思路。
但是发现我们如果每次去搜索的话,它的时间复杂度很低,每一次大于原来的答案就退出。
所以时间复杂度是 O ( l o g 2 n ) O(log_2^n) O(log2n)?
#include<bits/stdc++.h>
using namespace std;
int a,b,T,ans;
void dfs(int a,int b,int s){
if(s>=ans) return;
if(!a){
ans=s;
return;
}
if(b==1) dfs(a,b+1,s+1);
else dfs(a/b,b,s+1),dfs(a,b+1,s+1);
}
int main(){
scanf("%d",&T);
for (;T;T--){
scanf("%d%d",&a,&b);
if (a<b) printf("1\n");
else if (a==b) printf("2\n");
else{
ans=1000000000;
dfs(a,b,0);
printf("%d\n",ans);
}
}
return 0;
}
B. Replace and Keep Sorted:数学+统计
答案显然为 ∑ i = l r a i − a i − 2 − 2 \begin{aligned}\sum_{i=l}^{r}{a_i-a_{i-2}-2}\end{aligned} i=l∑rai−ai−2−2(不考虑边界情况)。
然后尝试化简。
∑
i
=
l
r
a
i
−
a
i
−
2
−
2
=
∑
i
=
l
r
a
i
−
a
i
−
2
−
2
(
r
−
l
+
1
)
=
a
r
−
a
l
+
k
+
1
−
2
(
r
−
l
+
1
)
=
a
r
−
a
l
+
k
−
2
(
r
−
l
)
−
1
\sum_{i=l}^{r}{a_i-a_{i-2}-2}\\ =\sum_{i=l}^{r}{a_i-a_{i-2}}-2(r-l+1)\\ =a_r-a_l+k+1-2(r-l+1)\\ =a_r-a_l+k-2(r-l)-1
i=l∑rai−ai−2−2=i=l∑rai−ai−2−2(r−l+1)=ar−al+k+1−2(r−l+1)=ar−al+k−2(r−l)−1
直接计算即可。
#include<bits/stdc++.h>
using namespace std;
int n,q,k,a[100005];
int main(){
scanf("%d%d%d",&n,&q,&k);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
while (q--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",k+a[r]-a[l]-2*(r-l)-1);
}
return 0;
}
C. Floor and Mod:数学+统计
设 k = ⌊ a b ⌋ = a m o d b k=\lfloor\frac a b\rfloor=a\mod b k=⌊ba⌋=amodb。
可以得到
a
=
k
b
+
k
a=kb+k
a=kb+k。
∵
b
>
k
,
∴
k
2
<
k
b
+
k
.
∴
k
2
<
a
.
∴
k
≤
a
.
\because b>k,\\ \therefore k^2<kb+k.\\ \therefore k^2<a.\\ \therefore k\leq \sqrt a.
∵b>k,∴k2<kb+k.∴k2<a.∴k≤a.
枚举
k
k
k,对于每一个
k
k
k,统计答案。
有两个式子 1 ≤ b ≤ y , 1 ≤ k b + k ≤ x 1\leq b\leq y,1\leq kb+k\leq x 1≤b≤y,1≤kb+k≤x,第二个式子移项一下就是 1 ≤ b ≤ ⌊ x k ⌋ − 1 1\leq b\leq \lfloor\frac xk\rfloor-1 1≤b≤⌊kx⌋−1。
所以 1 ≤ b ≤ min { ⌊ x k ⌋ − 1 , y } 1\leq b\leq \min\{\lfloor\frac xk\rfloor-1,y\} 1≤b≤min{⌊kx⌋−1,y}。
但是我们要保证 b > k b>k b>k,所以 b b b的取值范围就是 ( k , min { ⌊ x k ⌋ − 1 , y } ] (k,\min\{\lfloor\frac xk\rfloor-1,y\}] (k,min{⌊kx⌋−1,y}]。
注意可能没有答案或者答案小于 0 0 0,要与 0 0 0取 max \max max。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll x,y;
int main(){
scanf("%d",&T);
for (;T;T--){
scanf("%lld%lld",&x,&y);
ll ans=0;
for (ll k=1;k*k<x;k++){
ll up=min(x/k-1,y);
ll dn=k;
ans+=max(up-dn,(ll)0);
}
printf("%lld\n",ans);
}
return 0;
}
D. Multiples and Power Differences:数学+构造
其实我们每一个数都取 lcm ( 1 , 2 , 3 , . . . , 16 ) = 720720 \textrm {lcm}(1,2,3,...,16)=720720 lcm(1,2,3,...,16)=720720在加上某一个数即可。
什么时候加呢?
就保证相邻的至少有一个是加的即可。
也就是当 i + j i+j i+j是偶数,输出 720720 720720 720720,否则输出 720720 + a i , j 4 720720+a_{i,j}^4 720720+ai,j4,原因是保证满足是某个正整数的 4 4 4次方。
#include<bits/stdc++.h>
#define LCM 720720
using namespace std;
int n,m,a[505][505];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]),a[i][j]*=a[i][j],a[i][j]*=a[i][j];
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
if ((i+j)&1) printf("%d ",LCM+a[i][j]);
else printf("%d ",LCM);
}
}
return 0;
}