[SDOI2014]数表

题面就懒得放了,给个链接:LOJ
自己的想法:

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^m\sigma(\gcd(i.j))\\ &=\sum_{i=1}^n\sum_{j=1}^m\sum_{x|(i,j)}x\\ &=\sum_{x=1}^n\sum_{i=1}^{\frac{n}{x}}\sum_{j=1}^\frac{m}{x} \end{aligned} \]

然后就gg了,无法处理 \(\le a\) 的限制。
下面是正解(by Wolfycz):
2019-09-11 21-14-36 的屏幕截图.png

\(\sigma(P) = P +1\)
\(a\perp b,\)

\[\begin{aligned} \sigma(ab)&=\sum_{x|ab}x\\ &=\sum_{x|a}\sum_{y|b}xy\\ &=\sigma(a)\sigma(b) \end{aligned} \]

\(a\)包含\(p\)这个质因子

\[\sigma(pa) = \sigma(a) + \sigma(\frac{a}{low(a)})low(ap) \]

其中 \(low(x)\)\(x\) 最小质因子的指数次幂,若 \(x = \prod p_i^{c_i},p_1<p_2\cdots\) ,则 \(low(x) = p_1^{c_1}\)
然后就可以欧拉筛了。

\(\sigma\) 筛出来后,注意到 \(\sum_{d|T}\sigma(d)\mu(\frac{T}{d})\) 只有 \(\sigma(d)\le a\) 才会有贡献,所以我们把询问按 \(a\) 从小到大排序,然后把 \(\sigma(d) \le a\)\(\sigma(d)\mu(\frac{T}{d})\) 插入树状数组,枚举 \(d\) 的倍数,就可以做到 \(O(n\ln n\log n)\)

查询就数论分块+树状数组区间求和 \(O(q\sqrt n \log_2n)。\)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <fstream>

#define uint unsigned int
typedef long long LL;
typedef unsigned long long uLL;

#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define MP(x, y) std::make_pair(x, y)
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define GO cerr << "GO" << endl;

using namespace std;

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<class T> inline T read() 
{
	register T x(0);
	register char c;
	register int f(1);
	while (!isdigit(c = getchar())) if (c == '-') f = -1;
	while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
	return x * f;
}

template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }

const int maxN = 1e5;

struct Query
{
	uint n, m, id;
	uint ans;
	unsigned int a;
} q[maxN + 2];

struct BIT
{
	unsigned int t[maxN + 2];
	void add(int x, unsigned int y) { for (; x <= maxN; x += x & -x) t[x] += y; }
	unsigned int query(int x) 
	{
		unsigned int ans = 0;
		for (; x; x -= x & -x)
			ans += t[x];
		return ans;
	}
} T;

int Q;
bool vis[maxN + 2];
vector<unsigned int> prime;
pair<unsigned int, unsigned int> sigma[maxN + 2];
unsigned int mu[maxN + 2], low[maxN + 2];

void Input()
{
	Q = read<int>();
	for (int i = 1; i <= Q; ++i) 
		q[i].n = read<int>(), q[i].m = read<int>(), q[i].a = read<int>(), q[i].id = i;
}

void Init()
{
	sigma[1] = MP(1, 1);
	mu[1] = 1;
	for (register int i = 2; i <= maxN; ++i)
	{
		if (!vis[i])
		{
			mu[i] = -1;
			low[i] = i;
			sigma[i] = MP(1 + i, i);
			prime.push_back(i);
		}
		for (register int j = 0; j < SZ(prime) && prime[j] * i <= maxN; ++j)
		{
			int t = prime[j] * i;
			vis[t] = 1;
			if (i % prime[j] == 0)
			{
				low[t] = low[i] * prime[j];
				mu[t] = 0;
				sigma[t] = MP(sigma[i].first + low[t] * sigma[i / low[i]].first, t);
			}
			else
			{
				low[t] = prime[j];
				mu[t] = -mu[i];
				sigma[t] = MP(sigma[i].first * sigma[prime[j]].first, t);
			}
		}
	}
	//DEBUG("%d\n", sigma[9].first);
	sort(sigma + 1, sigma + 1 + maxN);
}

bool cmp(const Query& A, const Query& B) { return A.a < B.a; }
bool cmp2(const Query& A, const Query& B) { return A.id < B.id; }

void Solve()
{
	sort(q + 1, q + 1 + Q, cmp);
	int pos = 0;
	for (int i = 1; i <= Q; ++i)
	{
		while (sigma[pos + 1].first <= q[i].a and pos < maxN)
		{
			pos++;
			for (int j = 1; j * sigma[pos].second <= maxN; ++j)
				T.add(sigma[pos].second * j, sigma[pos].first * mu[j]);
		}
		unsigned int ans = 0;
		if (q[i].n > q[i].m) swap(q[i].n, q[i].m);
		int n = q[i].n, m = q[i].m;
		for (register int l = 1, r; l <= n; l = r + 1)
		{
			r = min(n / (n / l), m / (m / l));
			ans += (T.query(r) - T.query(l - 1)) * (n / l) * (m / l);
		}
		q[i].ans = ans & 0x7FFFFFFF;
	}
	sort(q + 1, q + 1 + Q, cmp2);
	for (int i = 1; i <= Q; ++i)
		printf("%d\n", q[i].ans);
}

int main() 
{
#ifndef ONLINE_JUDGE
	freopen("xhc.in", "r", stdin);
	freopen("xhc.out", "w", stdout);
#endif
	Input();
	Init();
	Solve();
	return 0;
}
posted @ 2019-09-12 08:50  茶Tea  阅读(154)  评论(1编辑  收藏  举报