2021牛客寒假算法基础集训营2 D.牛牛与整除分块(数论)
题目链接:https://ac.nowcoder.com/acm/contest/9982/D(付费比赛)
题面:
题解:考虑集合
S
S
S 中的元素组成,首先集合
S
S
S 中一定存在元素
{
1
,
2
,
⋯
,
⌊
N
⌋
−
1
}
\{1,2,\cdots,\lfloor\sqrt{N}\rfloor-1\}
{1,2,⋯,⌊N⌋−1} 。这是因为:
∀ i ∈ [ ⌊ N 2 ⌋ + 1 , N ] \forall i\in[\lfloor\frac{N}{2}\rfloor+1,N] ∀i∈[⌊2N⌋+1,N],有 ⌊ N i ⌋ = 1 \lfloor\frac{N}{i}\rfloor =1 ⌊iN⌋=1 ,
∀ i ∈ [ ⌊ N 3 ⌋ + 1 , ⌊ N 2 ⌋ ] \forall i\in[\lfloor\frac{N}{3}\rfloor+1,\lfloor\frac{N}{2}\rfloor] ∀i∈[⌊3N⌋+1,⌊2N⌋],有 ⌊ N i ⌋ = 2 \lfloor\frac{N}{i}\rfloor =2 ⌊iN⌋=2 ,
⋯ ⋯ \cdots\cdots ⋯⋯
∀ i ∈ [ ⌊ N ⌊ N ⌋ ⌋ + 1 , ⌊ N ⌊ N ⌋ − 1 ⌋ ] \forall i\in[\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor+1,\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor-1}\rfloor] ∀i∈[⌊⌊N⌋N⌋+1,⌊⌊N⌋−1N⌋],有 ⌊ N i ⌋ = ⌊ N ⌋ − 1 \lfloor\frac{N}{i}\rfloor =\lfloor\sqrt{N}\rfloor-1 ⌊iN⌋=⌊N⌋−1 。
因此,集合
S
S
S 一定包含
1
1
1 到
⌊
N
⌋
−
1
\lfloor\sqrt{N}\rfloor-1
⌊N⌋−1 的自然数。显然,对于剩下的区间 :
∀
i
,
j
∈
[
1
,
⌊
N
⌊
N
⌋
⌋
]
(
i
≠
j
)
\forall i,j\in[1,\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor](i\neq j)
∀i,j∈[1,⌊⌊N⌋N⌋](i=j),有
⌊
N
i
⌋
≠
⌊
N
j
⌋
\lfloor\frac{N}{i}\rfloor \neq\lfloor\frac{N}{j}\rfloor
⌊iN⌋=⌊jN⌋ ,且对于
⌊
N
⌊
N
⌋
⌋
\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor
⌊⌊N⌋N⌋ ,有
⌊
N
⌊
N
⌋
⌋
=
⌊
N
⌋
+
1
\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor=\lfloor\sqrt{N}\rfloor+1
⌊⌊N⌋N⌋=⌊N⌋+1 或
⌊
N
⌊
N
⌋
⌋
=
⌊
N
⌋
\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor=\lfloor\sqrt{N}\rfloor
⌊⌊N⌋N⌋=⌊N⌋ 。那么,这个集合的元素即为
{
1
,
2
,
3
,
⋯
,
⌊
N
3
⌋
,
⌊
N
2
⌋
,
N
}
\{1,2,3,\cdots,\lfloor\frac{N}{3}\rfloor,\lfloor\frac{N}{2}\rfloor,N\}
{1,2,3,⋯,⌊3N⌋,⌊2N⌋,N} ,当且仅当
⌊
N
⌊
N
⌋
⌋
=
⌊
N
⌋
\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor=\lfloor\sqrt{N}\rfloor
⌊⌊N⌋N⌋=⌊N⌋ 时,这个集合会减少一个重复的元素
⌊
N
⌋
\lfloor\sqrt{N}\rfloor
⌊N⌋ ,或者说是
⌊
N
⌊
N
⌋
⌋
\lfloor\frac{N}{\lfloor\sqrt{N}\rfloor}\rfloor
⌊⌊N⌋N⌋ 。
不难看出,这个集合的左右部分是有机关联的,在每个对称的位置
(
x
,
y
)
(x,y)
(x,y) 上,一定有
⌊
N
x
⌋
=
y
\lfloor\frac{N}{x}\rfloor=y
⌊xN⌋=y ,且这个集合的元素数目总量总是
2
⌊
N
⌋
2\lfloor\sqrt{N}\rfloor
2⌊N⌋ 或
2
⌊
N
⌋
−
1
2\lfloor\sqrt{N}\rfloor-1
2⌊N⌋−1 。那么对于任意一个数
⌊
N
x
⌋
\lfloor\frac{N}{x}\rfloor
⌊xN⌋ ,我们总可以根据它是否大于
⌊
N
⌋
\lfloor\sqrt{N}\rfloor
⌊N⌋ 来分别判别它的位置。如果大于
⌊
N
⌋
\lfloor\sqrt{N}\rfloor
⌊N⌋ ,那么数
x
x
x 就是它所在的降序序列的位置,反之,可以通过观察这个元素的对称位置来间接查找它的位置。
下面是AC代码。
#include<bits/stdc++.h>
using namespace std;
int main(){
int T,N,x;
scanf("%d",&T);
while(T--){
scanf("%d %d",&N,&x);
int z=sqrt(N);
int ans=2*z-N/x+1;
if(z==N/z) --ans;
if(x<=z) printf("%d\n",x);
else printf("%d\n",ans);
}
}