Nowcoder9982D.牛牛与整除分块(财富密码)

链接:https://ac.nowcoder.com/acm/contest/9982/D
来源:牛客网

题目描述

整除分块,又称数论分块。是数论算法中的重要技巧,你可以在各种需要枚举因子的连续求和类问题中见到它的身影。如杜教筛,莫比乌斯反演化简后的整除分段求和等。
整除分块基于这样一个数学现象:对于任意正整数N,集合S={x:x=⌊Ni⌋,i∈1,2,3...N}S=\left \{ x:x=\left \lfloor \frac{N}{i} \right \rfloor ,i\in 1,2,3...N \right \}S={x:x=iN,i1,2,3...N}的大小总是严格小于2N2 \sqrt N2N
例如当N=10时S={10,5,3,2,1},这就使得对于⌊Ni⌋\left \lfloor \frac{N}{i} \right \rflooriN⌋类型的求和类问题,只要快速枚举S集合,就能在N\sqrt NN级别的复杂度内解决问题。

⌊    ⌋\left \lfloor \; \; \right \rfloor⌋符号是向下取整符,⌊x⌋\left \lfloor x \right \rfloorx⌋表示不大于x的最大正整数

牛牛在学习整除分块这一算法后提出了一个新的问题,对于给定正整数N,x,令S={x:x=⌊Ni⌋,i∈1,2,3...N}S=\left \{ x:x=\left \lfloor \frac{N}{i} \right \rfloor ,i\in 1,2,3...N \right \}S={x:x=iN,i1,2,3...N},时⌊Nx⌋\left \lfloor \frac{N}{x} \right \rfloorxN⌋在S中是第几大呢(去重降序排序后第几个)?
 
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e6+100;
int main () {
    int t,n,x;
    scanf("%d",&t);
    while (t--) {
        scanf("%d%d",&n,&x);
        long long ans=0;
        int tt=sqrt(n);
        int y=tt*2;
        if (tt*(tt+1)>n) y--;
        //printf("%d\n",tt);
        if (x>tt)
            ans=y-n/(x)+1;
        else
            ans=x; 
        printf("%lld\n",ans);
    }
}

 

posted @ 2021-02-03 20:08  zlc0405  阅读(132)  评论(0编辑  收藏  举报