首页 > 其他分享 >[SDOI2018]旧试题

[SDOI2018]旧试题

时间:2023-05-31 22:46:14浏览次数:50  
标签:lfloor frac 试题 sum rfloor mu SDOI2018 nw

题意

求如下表达式的值

\[\sum_{i=1}^A \sum_{j=1}^B \sum_{k=1}^Cd(ijk) \bmod (10^9+7) \]

其中, \(A,B,C \leqslant 10^5\)

solution

先考虑如何处理后面的\(d(ijk)\)

根据[SDOI]2015约数个数和可知,通过简单的映射关系,有,

\[d(ijk) = \sum_{u|i}\sum_{v|j}\sum_{w|k}[gcd(u, v)=1]\times[gcd(u,w)=1]\times[gcd(v,w)=1] \]

则有,

\[\sum_{i=1}^A \sum_{j=1}^B \sum_{k=1}^Cd(ijk) \]

\[= \sum_{i=1}^A \sum_{j=1}^B \sum_{k=1}^C \sum_{u|i}\sum_{v|j}\sum_{w|k}[gcd(u, v)=1]\times[gcd(u,w)=1]\times[gcd(v,w)=1])) \]

\[= \sum_{i=1}^A \sum_{j=1}^B \sum_{k=1}^C \sum_{u|i}\sum_{v|j}\sum_{w|k}\epsilon(gcd(u, v))\times\epsilon(gcd(u,w))\times\epsilon(gcd(v,w)) \]

根据莫比乌斯反演的经典小把戏,尝试把因子提前枚举,

\[= \sum_{u=1}^A \sum_{v=1}^B \sum_{w=1}^C \sum_{u|i} \sum_{v|j} \sum_{w|k} \epsilon(gcd(u, v))\times\epsilon(gcd(u,w))\times\epsilon(gcd(v,w)) \]

\[= \sum_{u=1}^A \sum_{v=1}^B \sum_{w=1}^C \lfloor \frac{A}{u} \rfloor \lfloor \frac{B}{v} \rfloor \lfloor \frac{C}{w} \rfloor \epsilon(gcd(u, v))\epsilon(gcd(u,w))\epsilon(gcd(v,w)) \]

由莫比乌斯反演的基本推论:

\[\sum_{i=1}^{A} \sum_{j=1}^{B} \epsilon(gcd(i,j)) = \sum_{i=1}^{A} \sum_{j=1}^{B} \sum_{d|gcd(i,j)} \mu(d) = \sum_{i=1}^{A} \sum_{j=1}^{B} \sum_{d|i , d|j} \mu(d) \]

则有,

\[= \sum_{u=1}^A \sum_{v=1}^B \sum_{w=1}^C \lfloor \frac{A}{u} \rfloor \lfloor \frac{B}{v} \rfloor \lfloor \frac{C}{w} \rfloor \sum_{a|u,a|v} \mu(a) \sum_{b|u,b|w} \mu(b) \sum_{c|v,c|w} \mu(c) \]

再次交换求和号,

\[=\sum_{a=1}^{min\{A,B\}} \sum_{b=1}^{min\{A,C\}} \sum_{c=1}^{min\{B,C\}} \mu(a) \ \mu(b) \ \mu(c) \ \sum_{lcm(a,b)|u} \lfloor \frac{A}{u} \rfloor \sum_{lcm(a,c)|v} \lfloor \frac{B}{v} \rfloor \sum_{lcm(b,c)|w} \lfloor \frac{C}{w} \rfloor \]

\[=\sum_{a=1}^{min\{A,B\}} \sum_{b=1}^{min\{A,C\}} \sum_{c=1}^{min\{B,C\}} \mu(a) \ \mu(b) \ \mu(c) \ \sum_{u} \lfloor \frac{A}{u\times lcm(a,b)} \rfloor \sum_{v} \lfloor \frac{B}{v \times lcm(a,c)} \rfloor \sum_{w} \lfloor \frac{C}{w \times gcd(b,c)} \rfloor \]

记\(F(n)=\sum_{i} \lfloor \frac{n}{i} \rfloor = \sum_{i=1}^{n}d(i)\),则有,

\[=\sum_{a=1}^{min\{A,B\}} \sum_{b=1}^{min\{A,C\}} \sum_{c=1}^{min\{B,C\}} \mu(a) \ \mu(b) \ \mu(c) \ F(\lfloor \frac{A}{lcm(a,b)} \rfloor) F(\lfloor \frac{B}{lcm(a,c)} \rfloor) F(\lfloor \frac{C}{gcd(b,c)} \rfloor) \]

然后经过一顿操作,一个\(O(n^3)\)成功变成了另一个\(O(n^3)\)的式子

但是可以通过\(O(n \log n)\)的预处理,提前计算出所有\(F(n)\)的值,至少更加便于处理了

考虑这个式子值非零的条件,则\((a,b,c)\)需要满足:

\[\mu(a) \ne 0 , \mu(b) \ne 0, \mu(c) \ne 0, lcm(a,b) \leqslant A, lcm(a,c) \leqslant B, lcm(b, c) \leqslant C \]

后面三个条件不容易考虑,可以从前三个条件下手,不难发现\(a,b,c\)都必须为若干指数为\(1\)的质数的积

不难有暴力dfs,暴力枚举质数的积,然后分别计算其对应的式子的值,时间复杂度为\(O(9592^7)\),甚至不如\(O(n^3)\)的时间效率好

那么考虑一些优化技巧,或许能够发现我们可以在\(max\{A,B,C\}\)较小时,使用\(O(n^3)\)进行枚举,而对于其值较大时,考虑使用暴力dfs解决问题,分别来考虑:

记\(f(A,B,C) = \sum_{i=1}^A \sum_{j=1}^B \sum_{k=1}^Cd(ijk)\)

对于\(O(n^3)\)枚举部分,利用本题答案的定义式,根据容斥定理,则有,

\[f(A,B,C) = \sum_{m_i \in M}(-1)^{\tau(m_i)-1} \times f(A - m_{i,1}, B - m_{i,2}, C - m_{i,3}) + d(ABC) \]

其中,\(M\)为除\(\{0,0,0\}\)外其他由三个\(0\)或\(1\)组成的\(7\)个有限数列的集合,\(m_i\)为集合中的一个有限数列,\(\tau(i)\)为\(m_i\)中\(1\)的数量

(写的还不如说的明白,那写个锤子的数学表达式...)

这样便\(O(n^3)\)的时间复杂度下解决了较小\(max\{A,B,C\}\)下的值的求解

接下来解决\(max\{A,B,C\}\)较大时暴力dfs的求解,考虑到原定义式的运算规模较大,我们可以通过推出式来进行爆搜

简化问题规模,对于某个特定质数因子\(p_i\),分别考虑\(a,b,c\)中是否含有因子\(p\),不妨先假设\(a\)中含有质因子\(p\),那么对于这个特定\(a\)的值存在等式,

\[g(A,B,C) \]

\[=\sum_{b=1}^{min\{A,C\}} \sum_{c=1}^{min\{B,C\}} \mu(a) \ \mu(b) \ \mu(c) \ F(\lfloor \frac{A}{lcm(a,b)} \rfloor) F(\lfloor \frac{B}{lcm(a,c)} \rfloor) F(\lfloor \frac{C}{gcd(b,c)} \rfloor) \]

\[=\sum_{b=1}^{min\{A,C\}} \sum_{c=1}^{min\{B,C\}} (-1) \ \mu(\frac{a}{p}) \ \mu(b) \ \mu(c) \ F(\lfloor \frac{A}{lcm(\frac{a}{p},b) \times p} \rfloor) F(\lfloor \frac{B}{lcm(\frac{a}{p},c) \times p} \rfloor) F(\lfloor \frac{C}{gcd(b,c)} \rfloor) \]

\[=-g(\frac{A}{p}, \frac{B}{p}, C) \]

显然对于任意的\(a\),对于任意的质数因子\(p\),该等式同步成立,则有,

\[G(A,B,C) = \sum_{p|a}^A g(A, B, C) = -\sum_{p|a}^A g(\lfloor \frac{A}{p} \rfloor, \lfloor \frac{B}{p} \rfloor, C) = -G(\lfloor \frac{A}{p} \rfloor , \lfloor \frac{B}{p} \rfloor, C) \]

显然,对于\(b,c\),该性质同步存在,记\(i\)为当前筛选到第\(i\)个质数\(p_i\),\(dfs(i, A, B, C)\)为筛选到\(p_i\)时\(f(A,B,C)\)的值,不难设计dfs方案,

\[dfs(i,A,B,C) = \sum_{m_i \in M}(-1)^{\tau(m_i)} \times dfs(i + 1, \lfloor \frac{A}{m_{i,1} \lor m_{i,2} }\rfloor, \lfloor \frac{B}{m_{i,1} \lor m_{i,3} }\rfloor, \lfloor \frac{C}{m_{i,2} \lor m_{i,3} }\rfloor) \]

其中,\(M\)为全体由三个\(0\)或\(1\)组成的\(8\)个有限数列的集合,\(m_i\)为集合中的一个有限数列,\(\tau(i)\)为\(m_i\)中\(1\)的数量

当遍历完全部质数时,无论剩余的范围为多大,显然只能由\((a=1, b=1, c=1)\)做出贡献\(F(A) \times F(B) \times F(C)\),否则其\(\mu\)值为\(0\)

不难计算,这个暴力dfs的时间复杂度为\(O(8^{9592})\),但是由于\(A,B,C\)上界的存在,实际运行效率远优于此,但是在本题还是无法通过,考虑剪枝:

  1. 由于我们已经对\(max\{A,B,C\}\)较小时的方案进行了预处理,显然我们优先考虑较大的质数会使得整个搜索树更小

  2. 当目前遍历到的素数\(p_i \geqslant max\{A,B,C\}\)时,显然可以直接返回我们先前的预处理值\(f(A,B,C)\),否则会因为已经除去部分因子而导致我们的预处理值发生改变

  3. 发现当\(a,b,c\)中有至少两个数字可以被\(p\)整除时,不难发现dfs的返回值不变,只有符号发生变化,可以只递归一次dfs,然后将返回值两倍加入当前的答案

在这些剪枝的基础下,代码可以跑的飞快,完全不需要经历痛苦的卡常过程就可以A掉这题

Code

点击查看代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 1e5 + 50;
const int M = 31;
const int mod = 1e9 + 7;

inline int read() {
	int res = 0, f = 1;
	char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		res = (res << 3) + (res << 1) + c - '0';
		c = getchar();
	}	
	return res * f;
}

inline int add_mod(int a, int b) {
	a += b;
	if (a < 0)  a += mod;
	if (a >= mod)  a -= mod;
	return a;
}
inline int del_mod(int a, int b) {
	a -= b;
	if (a < 0)  a += mod;
	if (a >= mod)  a -= mod;
	return a;
}
inline int mul_mod(int a, int b) {
	a = 1ll * a * b % mod;
	return a;
}

int num;
int prime[N], d[N];
bool v[N];

int f[N];
int dp[M][M][M];

void init() {
	int n = 1e5;
	for (int i = 1; i <= n; ++i)  d[i] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!v[i]) {
			prime[++num] = i;
			for (int j = 1; j <= n / i; ++j) {
				v[i * j] = 1;
				d[i * j] += d[j];
			}
		}
	}
	for (int i = 1; i <= n; ++i)  f[i] = add_mod(f[i - 1], d[i]);
	reverse(prime + 1, prime + 1 + num);
	for (int i = 1; i < M; ++i)
		for (int j = 1; j < M; ++j)	
			for (int k = 1; k < M; ++k)
				dp[i][j][k] = (0ll + dp[i - 1][j][k] + dp[i][j - 1][k] + dp[i][j][k - 1] - dp[i - 1][j - 1][k] - dp[i - 1][j][k - 1] - dp[i][j - 1][ k - 1] + dp[i - 1][j - 1][k - 1] + d[i * j * k]) % mod;
}

inline int dfs(int nw, int a, int b, int c) {
	int maxx = max(max(a, b), c);
	if (!a || !b || !c)  return 0;
	if (!prime[nw])  return mul_mod(f[a], mul_mod(f[b], f[c]));
	if (prime[nw] > maxx && maxx < M)  return dp[a][b][c];
	int res = dfs(nw + 1, a, b, c);
	if (a >= prime[nw] && b >= prime[nw])  res = del_mod(res, dfs(nw + 1, a / prime[nw], b / prime[nw], c));
	if (a >= prime[nw] && c >= prime[nw])  res = del_mod(res, dfs(nw + 1, a / prime[nw], b, c / prime[nw]));
	if (b >= prime[nw] && c >= prime[nw])  res = del_mod(res, dfs(nw + 1, a, b / prime[nw], c / prime[nw]));
	if (a >= prime[nw] && b >= prime[nw] && c >= prime[nw]) res = add_mod(res, mul_mod(dfs(nw + 1, a / prime[nw], b / prime[nw], c / prime[nw]), 2));
	return res;
}

int A, B, C;

int main () {
	init();
	int T = read();
	while (T--) {
		A = read(), B = read(), C = read();
		int cnt = 1;
		while (prime[cnt] > A && prime[cnt] > B && prime[cnt] > C)  ++cnt;
		printf("%d\n", dfs(cnt, A, B, C));
	}
    return 0;
}

杂记

感谢_rqy的博客提供的idea,清芷姐姐太强力(说实话真没看懂rqy博客的细节内容,细节都是自己一点一点填的)

上次写赛博笔记都已经是三年半之前了,时间过得真快啊

顺便闲的没事搞了一个cnblogs,顺手发上去叭

标签:lfloor,frac,试题,sum,rfloor,mu,SDOI2018,nw
From: https://www.cnblogs.com/abigjiong/p/17446718.html

相关文章

  • 课堂测试题目
    2021级《软件工程》开发技能测试试卷(180分钟) 河北宏志大学学生成绩管理系统(卷面成绩40分) 河北宏志大学学生成绩管理系统1、项目需求:学生管理是各大院校的管理工作中尤为重视的一项工作,它一直以来是学校管理的一项重要的衡量指标。学生管理系统的应用解决了学校日常学生......
  • 考试题加面试常问问题
    1编写⼀个函数,接受⼀个字符串作为参数,并返回该字符串的反转结果2写出你知道的Python魔法⽅法及作⽤(5个以上)defreverse_string(string):returnstring[::-1]init(self,...):初始化⽅法,⽤于在创建对象时进⾏初始化操作。str(self):返回对象的字符串表示,可以通过str(obj)......
  • java面试题
    一、面向对象的特性有哪些?封装(Encapsulation):将数据和方法封装在一个类中,通过访问修饰符控制数据的访问权限,提高程序的安全性和可维护性。继承(Inheritance):可以从父类继承属性和方法,避免重复编写代码,简化程序设计和维护。多态(Polymorphism):同一种类型的对象,可以以不同的方式......
  • 1万7千道法律职业考试题ACCESS\EXCEL数据库
    今天这个《1万7千道法律职业考试题ACCESS数据库》集收了海量的法考题库试题,是从法律职业考试软件取提出来的,让你备考通关更加高效。今天这个《1万7千道法律职业考试题ACCESS数据库》集收了海量的法考题库试题,是从法律职业考试软件取提出来的,让你备考通关更加高效。包含分类:1.法......
  • 智能网联汽车概论试题库
    怎么不经允许就售卖他人劳动成果啊?还请各位别去“小木屋”等打印,谢谢!本文使用markdown编写,部分内容格式没识别出来,懒得改了,又不是写出来给奸商偷去售卖的……第1章智能网联汽车基础知识(一)名称解释(每题2分,共10分)智能汽车:是指搭载先进的车载传感器、控制系统、执行器等装置......
  • Java中Collection与Collections有什么区别?Java常见面试题解析
    本文将为大家详细讲解Java中Collection与Collections的区别点,这是我们进行开发时经常用到的知识点,也是大家在学习Java中很重要的一个知识点,更是我们在面试时有可能会问到的问题!文章较长,干货满满,建议大家收藏慢慢学习。文末有本文重点总结,主页有全系列文章分享。技术类问题,欢迎大......
  • java 面试题目
    1:子类和父类的实例变量和方法有什么区别?2:重载和覆盖的区别,返回类型不同,可以重载吗?为什么?底层如何实现的?3:抽象类与接口的区别4:悲观锁和乐观锁5:线程安全的解决方法有哪些?读写锁6:hashcode和equals?7:java泛型8:ThreadLocal,Concurrent下面的包,原理?9:AtomicInteger原理是什......
  • Swoole 面试题总结
    swoole提升性能1.进程常驻内存:swoole本⾝是进程常驻内存,在进程启动的时候就将PHP框架等代码读取并编译完成,不需要每次启动的时候都执⾏编译步骤,⼤⼤降低了脚本的运⾏时间;2.连接池php-fpm的模式php因为每次请求结束时都会销毁所有资源,因此⽆法使⽤连接池;⽽基于swoole的进程常驻......
  • java实现导入word模板导入试题
    ​ 最近有一个项目需要将一个word文档中的试题数据导入,并存储到数据库中。试题类型包括:单选题、多选题、判断题、填空题、简答题。支持图片导入(我的这篇是借鉴JAVA实现Excel、Word模板导入-JAVA-华仔部落,javapoi解析上传word试卷(题库管理系统)-爱码网)这两位大神的。废话......
  • 当涉及到基本数据类型和包装类时,一些你需要了解、可能容易被忽略的细节。(附面试题)
    基本数据类型Java基本数据按类型可以分为四大类:布尔型、整数型、浮点型、字符型,这四大类包含8种基本数据类型。布尔型:boolean整数型:byte、short、int、long浮点型:float、double字符型:char8种基本类型取值如下:数据类型代表含义默认值取值包装类boolean布尔型false0(false)到1(......