2020牛客多校第七場H-Dividing
阿新 • • 發佈:2020-09-08
https://ac.nowcoder.com/acm/contest/5672/H
題意
正整數二元組 Legend Tuple (n, k) 是這樣定義的
-
(1, k) 總是 Legend Tuple
-
若 (n, k) 是 Legend Tuple, 那麼 (n + k, k) 也是
-
若 (n, k) 是 Legend Tuple, 那麼 (nk, k) 也是
統計有多少個 Legend Tuple (n, k) 滿足 1 ≤ n ≤ N, 1 ≤ k ≤ K, 其中 N 和 K 是不超過 10^12 的整數
題解
可以很容易發現答案即為n%k==0,或者(n-1)%k==0的對數
對於一部分k,n/k是相等的,所以可以直接整除分塊,分別計算情況1和情況2的答案即可
但要注意整除分塊的r邊界不要超過k,否則會導致答案錯誤
因為這點wa了好幾發
程式碼
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct READ { inline char read() { #ifdef _WIN32 return getchar(); #endif static const int IN_LEN = 1 << 18 | 1; static char buf[IN_LEN], *s, *t; return (s == t) && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)), s == t ? -1 : *s++; } template <typename _Tp> inline READ & operator >> (_Tp&x) { static char c11, boo; for(c11 = read(),boo = 0; !isdigit(c11); c11 = read()) { if(c11 == -1) return *this; boo |= c11 == '-'; } for(x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0'); boo && (x = -x); return *this; } } in; const int N = 2e5 + 50; const ll p = 1e9 + 7; int main() { ll n, k; in >> n >> k; ll ans = 0; for (ll l = 1, r; l <= k; l = r + 1) { ll x = (n / l); if (x == 0) break; r = n / x; r = min(r, k); ans = (ans + ((r - l + 1) % p) * ((n / l) % p) % p) % p; } for (ll l = 2, r; l <= k; l = r + 1) { ll x = (n - 1) / l; if (x == 0) { ans = (ans + k - l + 1) % p; break; } r = (n - 1) / x; r = min(r, k); ans = (ans + ((r - l + 1) % p) * (((n - 1) / l + 1) % p) % p) % p; } printf("%lld\n", ans); return 0; } //1000000000000 1000000000000