BZOJ2693 jzptab

多次询问,求

\[\sum _ {i = 1} ^ {n} \sum _{j = 1} ^ {m} lcm(i, j) \]


题解写不动了……~~自己~~搞出来的和大佬们的都一样,就贴一发[大佬的博客](https://www.cnblogs.com/GXZlegend/p/7000042.html)吧。
如果不会的话,可以先做这个弱化版的:[单次询问](https://www.luogu.org/problemnew/show/P1829) 也附上一篇[大佬的博客](https://www.luogu.org/blog/peng-ym/solution-p1829)
这里有几个枚举的小技巧,比如其中有一项 $$\sum _ {x = 1} ^ {n} \sum_ {i = 1} ^ {\lfloor \frac{n}{d} \rfloor} \sum_ {j = 1} ^ {\lfloor \frac{m}{d} \rfloor} i j \sum _ {x | gcd(i, j)} \mu(x)$$ 我们发现$x | gcd(i, j)$这个条件很不爽,于是可以换一个思路:把枚举$i,j$变成枚举$ax, bx$。 嗯就这样…… ```c++ #include #include #include #include #include #include #include #include #include #include using namespace std; #define enter puts("") #define space putchar(' ') #define Mem(a, x) memset(a, x, sizeof(a)) #define rg register typedef long long ll; typedef double db; const int INF = 0x3f3f3f3f; const db eps = 1e-8; const int maxn = 1e7 + 5; const ll mod = 1e8 + 9; inline ll read() { ll ans = 0; char ch = getchar(), last = ' '; while(!isdigit(ch)) last = ch, ch = getchar(); while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); if(last == '-') ans = -ans; return ans; } inline void write(ll x) { if(x < 0) x = -x, putchar('-'); if(x >= 10) write(x / 10); putchar(x % 10 + '0'); }

int prm[maxn], v[maxn];
ll f[maxn], sum[maxn];
void init()
{
f[1] = 1;
for(int i = 2; i < maxn; ++i)
{
if(!v[i]) v[i] = i, prm[++prm[0]] = i, f[i] = ((i - (ll)i * i) % mod + mod) % mod;
for(int j = 1; i * prm[j] < maxn && j <= prm[0]; ++j)
{
v[i * prm[j]] = prm[j];
if(i % prm[j] == 0)
{
f[i * prm[j]] = f[i] * prm[j] % mod;
break;
}
f[i * prm[j]] = f[i] * f[prm[j]] % mod;
}
}
for(int i = 1; i < maxn; ++i) sum[i] = (sum[i - 1] + f[i]) % mod;

}

ll s(ll n)
{
return n * (n + 1) / 2 % mod;
}
ll solve(ll n, ll m)
{
ll ret = 0;
int Min = min(n, m);
for(int l = 1, r; l <= Min; l = r + 1)
{
r = min(n / (n / l), m / (m / l));
ret = (ret + s(n / l) * s(m / l) % mod * (sum[r] - sum[l - 1] + mod) % mod) % mod;
}
return ret;
}

int main()
{
init();
int T = read();
while(T--)
{
int n = read(), m = read();
write(solve(n, m)), enter;
}
return 0;
}

posted @ 2018-12-13 10:44  mrclr  阅读(89)  评论(0编辑  收藏  举报