2832: 小y爱数数
小y有$n$个数字$(1-n)$,他每次会在里面等概率随机选取两个数$x$,$y$(两个数互不影响),求$x%y==k$的概率(对23333取模)
保证$n%23333!=0$对$23333$取模的结果:假设答案化为最简分式后的形式为$a/b$, 其中$a$和$b$互质。
输出整数 x 使得 bx mod 23333 ≡ amod 23333 且 0<=x<=23333 (可以证明这样的整数 x 是唯一的)
一共T组询问,输出T组询问的答案的异或和
输入
第一行读入一个正整数T
接下来T行每一行读入两个整数n,k,
n≤1e5,0<=k<=10,T<=5e5
保证n%23333!=0
输出
输出一行一个数代表答案
样例输入 Copy
5
10 3
1 0
2 0
3 1
4 2
样例输出 Copy
13459
提示
样例中每组询问答案分别为7700,1,5834,7778,8750
首先当x>y时,x%y=k显然等价于x=ny+k;(n≥1)那么我们想到, 对于每个y和k,都有固定的x与之对应, 比如y+k, 2y+k...那么我们可以枚举出每一个k和y的x的取值, 复杂度为, 由著名的调和级数得知, 复杂度为O(knlogn), 是可以过去的,我们枚举每一种方案数是, 可以用数组f[i][j]表示k为i, x为j的方案数, 那么求一个前缀和就是n为j的方案数。
再想一下, 当x<y时,如果k=0, 显然无解, 当k>0时, x只能是k, y可以取[k+1, n]之间的任意数, 特判一下即可。。
再想一下, 当x<y时,如果k=0, 显然无解, 当k>0时, x只能是k, y可以取[k+1, n]之间的任意数, 特判一下即可。。
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e5 + 10; const int maxn = 1e5; const int mod = 23333; template < typename T > inline void read(T &x) { x = 0; T ff = 1, ch = getchar(); while (!isdigit(ch)) { if (ch == '-') ff = -1; ch = getchar(); } while (isdigit(ch)) { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } x *= ff; } int T, n, k, ans = 0; int f[11][N]; inline int power(int a, int b) { int ans = 1; while (b) { if (b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans; } signed main() { // x % y == k for (int i = 0; i <= 10; ++i) { // 枚举k for (int j = i + 1; j <= maxn; ++j) // 枚举 y for (int k = 1; k * j + i <= maxn; ++k) // k*j+i是x ++f[i][k * j + i]; for (int j = 1; j <= maxn; ++j) f[i][j] = (f[i][j] + f[i][j - 1]) % mod; } //当x>=k时,x%y==k等价(x-k)%y==0 //上面都是保证x>y的 read(T); while (T--) { read(n), read(k); int cnt = f[k][n]; if (k != 0) cnt += max(n - k, 0ll); // 这里表示当x<y时,x只能时k, y可以是[k+1, n]之间的人任何数 cnt %= mod; cnt = cnt * power(n * n % mod, mod - 2) % mod; ans ^= cnt; } printf("%lld\n", ans); return 0; }