数字的升级准则

数子的升级准则

问题描述:

现有 \(n\) 个数字,分别是 \(1,2,3,...,n\),每个数字初始等级都为 \(0\),对于第 \(i\) 个数字每过 \(i\) 个时间就会升一级,例如 \(5\) 个数字过去 \(3\) 个时间后它们的等级分别是 \(3, 1, 1, 0, 0\)
问题来了,\(n\) 个数字经过 \(n\) 个时间后把他们的等级进行降序排序并去重后的得到一个等级表,那么你知道第 \(x\) 个数字的等级在这张等级表中排第几吗?
(ps:若 \(n=5\) 时降序排序为 {\(5,2,1,1,1\)},则去重后的等级表为{\(5,2,1\)})

输入描述

第一行输入一个正整数 \(T(1 \leq T \leq10^6)\),表示测试案例的数目,对于每组案例。
一行两个正整数\(n,x(1 \leq x \leq n\leq 10^9)\)

输出描述

对于每个案例,输出一个正整数表示答案。

示例

输入

2
25 9
1000000000 1000000000

输出

8
63244

思路:当 \(i*j \leq n\) 时,\(i\)\(j\) 在等级表中等级必定不一样,同时数字的等级满足数论分块(对称性),所以 \(O(1)\) 可做。

#include<bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T;
    cin >> T;
    while(T --) {
        int n, x;
        cin >> n >> x;
        int m = sqrt(n);
        if (n >= m*(m+1)) {
            if (x <= m + 1) cout << x << "\n";
            else cout << 2*m - n/x +1 << "\n";
        }
        else {
            if (x <= m) cout << x << "\n";
            else cout << 2*m -n/x << "\n";
        }
    }
    return 0;
}

posted @ 2021-02-03 19:17  Daowuu  阅读(84)  评论(0编辑  收藏  举报