ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

『题解』Luogu-P3312 [SDOI2014]数表

2022-02-03 21:04:46  阅读:123  来源: 互联网

标签:lfloor right 题解 P3312 le SDOI2014 sigma sum left


P3312 [SDOI2014]数表

Description

  • 多测,\(Q\) 组数据。
  • 有一张 \(n\times m\) 的数表,其第 \(i\) 行第 \(j\) 列(\(1\le i\le n, 1\le j\le m\))的数值为能同时整除 \(i\) 和 \(j\) 的所有自然数之和。给定 \(a\),计算数表中不大于 \(a\) 的数之和模 \(2^{31}\) 的值。
  • \(1\le n, m\le 10^5, 1\le Q\le 2\times 10^4, |a| \le 10^9\)。

Solution

首先模 \(2^{31}\) 就直接用 \(\text{int}\) 存自然溢出,最后和 \(2^{31} - 1\) 取 & 即可。

因为 \(k\mid n \land k\mid m \Leftrightarrow k\mid \gcd(n, m)\),所以第 \(i\) 行第 \(j\) 列的数是 \(\sigma(\gcd(i, j))\)。

先不考虑关于 \(a\) 的限制,则所求为

\[\begin{aligned} ans & = \sum_{i = 1}^n \sum_{j = 1}^m \sigma(\gcd(i, j)) \\ & = \sum_{i = 1}^n \sum_{j = 1}^m \sum_{d = 1}^n \sigma(d) [\gcd(i, j) = d] \\ & = \sum_{d = 1}^n \sigma(d) \sum_{i = 1}^{\left\lfloor\frac{n}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} [\gcd(i, j) = 1] \\ & = \sum_{d = 1}^n \sigma(d) \sum_{i = 1}^{\left\lfloor\frac{n}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor\frac{m}{d}\right\rfloor} \sum_{k\mid \gcd(i, j)} \mu(k) \\ & = \sum_{d = 1}^n \sigma(d) \sum_{k = 1}^{\left\lfloor\frac{n}{d}\right\rfloor} \mu(k) \left\lfloor\dfrac{n}{dk}\right\rfloor \left\lfloor\dfrac{m}{dk}\right\rfloor \\ & = \sum_{T = 1}^n \left\lfloor\dfrac{n}{T}\right\rfloor \left\lfloor\dfrac{m}{T}\right\rfloor \sum_{d\mid T} \sigma(d) \mu\left(\dfrac{T}{d}\right) \end{aligned} \]

\[f(n) = \sum_{d\mid n} \sigma(d) \mu\left(\dfrac{T}{d}\right) \]

如果没有关于 \(a\) 的限制,我们有 \(f = \sigma * \mu = \operatorname{Id}\)。

加上限制后,需要满足的是 \(\sigma(d) \le a\)。

我们运用莫队的思想,将所有的 \(\sigma\) 以及 \(a\) 从小到大排序,枚举 \(d\) 的倍数加贡献。

我们需要对 \(f\) 进行单点修改加贡献,数论分块区间查询,直接用树状数组即可。

预处理要枚举 \(n\ln n\) 次,还要修改,所以是 \(\Omicron(n\ln n\log n)\) 的;

查询有 \(\sqrt{n}\) 个块,块内要 \(\log n\) 查区间和,所以是 \(\Omicron(Q \sqrt{n} \log n)\) 的。

总时间复杂度为 \(\Omicron(n\log^2 n + Q \sqrt{n} \log n)\)。

Code

//18 = 9 + 9 = 18.
#include <iostream>
#include <cstdio>
#include <algorithm>
#define Debug(x) cout << #x << "=" << x << endl
typedef long long ll;
using namespace std;

const int MAXN = 1e5 + 5;
const int N = 1e5;
typedef int arr[MAXN];

arr p, mu, sigma, num;
bool vis[MAXN];

pair<int, int> f[MAXN];

void pre()
{
	mu[1] = sigma[1] = 1;
	for (int i = 2; i <= N; i++)
	{
		if (!vis[i])
		{
			p[++p[0]] = i;
			mu[i] = -1;
			sigma[i] = num[i] = 1 + i;
		}
		for (int j = 1; j <= p[0] && i * p[j] <= N; j++)
		{
			vis[i * p[j]] = true;
			if (i % p[j] == 0)
			{
				mu[i * p[j]] = 0;
				sigma[i * p[j]] = sigma[i] / num[i] * (num[i] * p[j] + 1);
				num[i * p[j]] = num[i] * p[j] + 1;
				break;
			}
			mu[i * p[j]] = mu[i] * mu[p[j]];
			sigma[i * p[j]] = sigma[i] * sigma[p[j]];
			num[i * p[j]] = 1 + p[j];
		}
	}
	for (int i = 1; i <= N; i++)
	{
		f[i] = {sigma[i], i};
	}
	sort(f + 1, f + N + 1);
}

arr c;

inline int lowbit(int x)
{
	return x & -x;
}

void update(int x, int k)
{
	for (int i = x; i <= N; i += lowbit(i))
	{
		c[i] += k;
	}
}

int query(int x)
{
	int res = 0;
	for (int i = x; i; i -= lowbit(i))
	{
		res += c[i];
	}
	return res;
}

int query_range(int l, int r)
{
	return query(r) - query(l - 1);
}

struct Query
{
	int id, n, m, a;
	bool operator <(const Query &x)const
	{
		return x.a > a;
	}
}q[MAXN];

arr ans;

int main()
{
	pre();
	int Q;
	scanf("%d", &Q);
	for (int i = 1; i <= Q; i++)
	{
		int n, m, a;
		scanf("%d%d%d", &n, &m, &a);
		q[i] = Query{i, n, m, a};
	}
	sort(q + 1, q + Q + 1);
	for (int t = 1, i = 0; t <= Q; t++)
	{
		int a = q[t].a, val;
		while ((val = f[i + 1].first) <= a)
		{
			int d = f[++i].second;
			for (int k = 1; d * k <= N; k++)
			{
				update(d * k, val * mu[k]);
			}
		}
		int id = q[t].id, n = q[t].n, m = q[t].m;
		if (n > m)
		{
			swap(n, m);
		}
		for (int l = 1, r; l <= n; l = r + 1)
		{
			int k1 = n / l, k2 = m / l;
			r = min(n / k1, m / k2);
			ans[id] += k1 * k2 * query_range(l, r);
		}
	}
	for (int i = 1; i <= Q; i++)
	{
		printf("%d\n", ans[i] & 2147483647);
	}
	return 0;
}

标签:lfloor,right,题解,P3312,le,SDOI2014,sigma,sum,left
来源: https://www.cnblogs.com/mangoworld/p/Solution-Luogu-P3312.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有