【做题】SRM704 Div1 Median - ModEquation——数论
原文链接 https://www.cnblogs.com/cly-none/p/SRM704Div1B.html
给出\(n\)和模数\(P\)。\(q\)次询问,每次给出一个\([0,P-1]\)范围内的整数\(v\),求有多少长度为\(n\)的序列\(\{x\}\)满足\(x_i\)都是\([0,P-1]\)范围内的整数且\(\prod x_i \equiv v \pmod P\),答案对\(10^9 + 7\)取模。
\(n \leq 50 , \ q \leq 10^3, \ P \leq 10^9\)
注意:\(P\)不是质数。
这题大概就是道结论题。
首先,我们容易得到\(O(n P^2)\)的dp。
考虑\(P\)为质数的情况。我们发现,对于所有\(a \neq 1\),\(\{a, 2a, \cdots, (P-1)a\}\)都是互不相等的,即它在模\(P\)意义下就是\(\{1, 2, \cdots , P-1\}\)。那么,在dp中\(1\)到\(P-1\)的所有数的转移都是相同的,那它们的答案也应当是相等的。
尝试把这个结论拓展到\(P\)为正整数的情况下。我们设模\(P\)意义下的每个数 $v = v' \times d $ ,其中 \(d=gcd(v,P)\) 。同样地,\(\{ v', 2v', \cdots , (P-1)v' \}\)互不相等,于是 \(v\) 乘以\(1\)到\(P-1\)的所有数就是\(\{d, 2d, \cdots , (P-1)d \}\)。于是,我们发现\(gcd(x,P)\)相同的\(x\)在dp中有相同的转移,那就可以把它们的状态合并在一起。这样这个dp就优化到了\(O(n \sigma (n)^2)\)的了,已经可以通过本题。
但我们还可以套路地对\(P\)做质因数分解,得到\(P = p_1^{a_1} p_2^{a_2} \cdots p_n^{a_n}\),然后以每个\(p_i^{a_i}\)为模数,分别求一次答案。考虑所有模\(P\)意义下的数和模\(p_i^{a_i}\)得到的序列是一一对应的,所以我们可知答案就是以每个\(p_i^{a_i}\)为模数的答案的积。那么,就能\(O(n \log^2 P + q \log P)\)地解决本题。(这里的\(\log P\)分析并不准确)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef double db;
#define fir first
#define sec second
class ModEquation {
public:
vector <int> count( int n, int K, vector <int> query ) ;
};
const int MAX = 100000, MP = 30, N = 60, MOD = (int)(1e9 + 7);
int isp[MAX + 10], pri[MAX], pcnt, fac[MP], fcnt, num[MP];
int power(int a,int b) {
int ret = 1;
while (b) {
if (b & 1) ret = 1ll * ret * a % MOD;
a = 1ll * a * a % MOD;
b >>= 1;
}
return ret;
}
void prework() {
for (int i = 2 ; i <= MAX ; ++ i) {
if (!isp[i]) pri[++pcnt] = i;
for (int j = 1 ; pri[j] * i <= MAX ; ++ j) {
isp[pri[j] * i] = 1;
if (i % pri[j] == 0) break;
}
}
}
int dp[MP][N][MP];
void init() {
pcnt = fcnt = 0;
memset(isp,0,sizeof isp);
memset(dp,0,sizeof dp);
}
vector <int> ModEquation::count(int n, int K, vector <int> query) {
init();
prework();
for (int i = 1 ; i <= pcnt ; ++ i) {
if (K % pri[i]) continue;
fac[++fcnt] = pri[i];
num[fcnt] = 0;
while (K % pri[i] == 0)
++ num[fcnt], K /= pri[i];
}
if (K != 1) {
++ fcnt;
fac[fcnt] = K;
num[fcnt] = 1;
}
for (int i = 1 ; i <= fcnt ; ++ i) {
dp[i][0][0] = 1;
for (int j = 0 ; j < n ; ++ j) {
for (int a = 0 ; a <= num[i] ; ++ a)
for (int b = num[i], t = 1 ; b >= 0 ; -- b, t *= fac[i]) {
(dp[i][j+1][min(num[i], a + b)] += 1ll * dp[i][j][a] * (t - t / fac[i]) % MOD) %= MOD;
}
}
for (int a = num[i], t = 1 ; a >= 0 ; -- a, t *= fac[i]) {
dp[i][n][a] = 1ll * dp[i][n][a] * power(t - t / fac[i], MOD - 2) % MOD;
}
}
vector<int> ans = vector<int>();
for (int id = 0 ; id < (int)query.size() ; ++ id) {
int v = query[id], ret = 1;
for (int i = 1 ; i <= fcnt ; ++ i) {
int tmp = v, rec = 0;
for (int j = 1 ; j <= num[i] ; ++ j)
if (tmp % fac[i] == 0) tmp /= fac[i], ++ rec;
ret = 1ll * ret * dp[i][n][rec] % MOD;
}
ans.push_back(ret);
}
return ans;
}
#undef fir
#undef sec
小结:数论题有一些基本结论和套路还是非常重要的。
【做题】SRM704 Div1 Median - ModEquation——数论的更多相关文章
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- noip做题记录+挑战一句话题解?
因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...
- NOIP2016考前做题(口胡)记录
NOIP以前可能会持续更新 写在前面 NOIP好像马上就要到了,感觉在校内训练里面经常被虐有一种要滚粗的感觉(雾.不管是普及组还是提高组,我都参加了好几年了,结果一个省一都没有,今年如果还没有的话感觉 ...
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- C语言程序设计做题笔记之C语言基础知识(上)
C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...
- 屏蔽Codeforces做题时的Problem tags提示
当在Codeforces上做题的时,有时会无意撇到右侧的Problem tags边栏,但是原本并不希望能够看到它. 能否把它屏蔽了呢?答案是显然的,我们只需要加一段很短的CSS即可. span.tag ...
- ACM 做题过程中的一些小技巧。
ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long l ...
- CodeM美团点评编程大赛复赛 做题感悟&题解
[T1] [简要题意] 长度为N的括号序列,随机确定括号的方向:对于一个已确定的序列,每次消除相邻的左右括号(右左不行),消除后可以进一步合并和消除直到不能消为止.求剩下的括号的期望.\(N \l ...
随机推荐
- eolinker使用初体验(一)
1.官网 https://www.eolinker.com 2.安装测试增强插件,由于chrome安装的时候有问题,建议移步firefox浏览器,不纠结.. 3.新建一个单例测试
- Jmeter压测基础(二)——Badboy功能、Jmeter参数化、检查点、集合点、动态关联、图形监控
Badboy 以下稍微介绍一下badboy的部分功能: 1.Record;play(badboy打开后默认是recording状态) 2.Assertion(检查点/断言) 3.Variable: t ...
- TestNG Suite 运行出现中文乱码如何解决
场景: 用TestNG框架运行测试类,控制台视图输出出现中文乱码. 解决方案: 1.eclipse属性>workspace>other>utf-8 2.修改eclipse.ini 文 ...
- ADB——查看手机设备信息
查看设备信息 查看手机型号 adb shell getprop ro.product.model 查看电池状况 adb shell dumpsys battery ''' Current Batter ...
- Es6的用法
var callBack=[]; // 这个等于是个闭包,i会累加到3在做运算,所以结果都是6 ;i<=;i++) { callBack[i]=function(){ ; } } console ...
- 一次 Spark SQL 性能提升10倍的经历(转载)
1. 遇到了啥问题 是酱紫的,简单来说:并发执行 spark job 的时候,并发的提速很不明显. 嗯,且听我慢慢道来,啰嗦点说,类似于我们内部有一个系统给分析师用,他们写一些 sql,在我们的 sp ...
- Java基础之数组详解
数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如 numbers[1 ...
- C#中方法、类等的默认访问修饰符~
C# 方法默认访问级别 : private C# 类默认访问级别 : internal 1.命名空间下的元素的默认访问修饰符 public : 同一程序集的其他任何代码或引用该程序集的其他程序集都可以 ...
- zabbix监控实战<1>
第一章 监控家族 1.1 为什么选择监控? 因为在一个IT集群中或者是一个大环境中,包括各种硬件设备.软件设备等系统的构成也是极其复杂的. 多种应用构成负载的IT业务系统,保证这些资源的正常运转,是一 ...
- 一般程序中的session
在WebHandler中无法访问session: IRequiresSessionState必须实现这个接口(不包含任何方法的标记接口), 需要导入using System.Web.SessionSt ...