原文链接 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——数论的更多相关文章

  1. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

  2. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  3. NOIP2016考前做题(口胡)记录

    NOIP以前可能会持续更新 写在前面 NOIP好像马上就要到了,感觉在校内训练里面经常被虐有一种要滚粗的感觉(雾.不管是普及组还是提高组,我都参加了好几年了,结果一个省一都没有,今年如果还没有的话感觉 ...

  4. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  5. C语言程序设计做题笔记之C语言基础知识(下)

    C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

  6. C语言程序设计做题笔记之C语言基础知识(上)

    C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...

  7. 屏蔽Codeforces做题时的Problem tags提示

    当在Codeforces上做题的时,有时会无意撇到右侧的Problem tags边栏,但是原本并不希望能够看到它. 能否把它屏蔽了呢?答案是显然的,我们只需要加一段很短的CSS即可. span.tag ...

  8. ACM 做题过程中的一些小技巧。

    ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long l ...

  9. CodeM美团点评编程大赛复赛 做题感悟&题解

    [T1] [简要题意]   长度为N的括号序列,随机确定括号的方向:对于一个已确定的序列,每次消除相邻的左右括号(右左不行),消除后可以进一步合并和消除直到不能消为止.求剩下的括号的期望.\(N \l ...

随机推荐

  1. 微信小程序样式旋转

    相关文档:http://www.w3school.com.cn/cssref/pr_transform.asp index.wxss文件 注意:如果是web前端,要注意浏览器的兼容性 .x1{ wid ...

  2. Spring boot +mybatis 连接mysql数据库,获取JDBC失败,服务器时区价值”Oйu±e×¼e±¼的识别或代表多个时区

    报出的错误 Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connec ...

  3. linux(centos7)设置tomcat开机启动

    1.在/etc/rc.d/rc.local中加入: #java environment export JAVA_HOME=/usr/java/jdk1.8.0_161 export CLASSPATH ...

  4. 转载,matla滤波函数

    转载地址http://blog.sina.com.cn/s/blog_6163bdeb0102e1dj.html 滤波器设计是一个创建满足指定滤波要求的滤波器参数的过程.滤波器的实现包括滤波器结构的选 ...

  5. Eclipse集成Hadoop插件

    一.Eclipse集成Hadoop插件 1.在这之前我们需要配置真机上的hadoop环境变量 注:在解压tar包的时候普通解压会出现缺文件的现象,所以在这里我们需要用管理员的方式启动我们的解压软件(我 ...

  6. what's the 黑盒测试

    what's the 黑盒测试 黑盒测试是把测试对象看做一个黑盒子,利用黑盒测试法进行动态测试时,需要测试软件产品已经实现的功能是否符合功能设计要求,不需测试软件产品的内部结构和处理过程. 黑盒测试注 ...

  7. robotframework接口之上传图片

    python-requests及robotframework-RequestsLibrary实现multipart/form-data接口上传文件. 如Fiddle抓包截图: 实现如截图: 不要自己在 ...

  8. 基于FPGA的视频时序生成

    之前用FPGA做过视频时序方面的设计,现将视频时序的设计方法分享给大家,希望对大家有所帮助. 时序部分可以参考CEA-861D,VESA时序标准. 1080P一帧视频中,一行有2200个像素,其中28 ...

  9. Centos7安装jexus,部署asp.net core,asp.net mvc

    什么是Jexus 官网解释:https://www.jexus.org/ Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,Jexus Web Service,简称JWS,以支持AS ...

  10. mysql中utf8和utf8mb4区别

    一.什么是utf8mb4 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在utf8mb4是utf8的超集,除 ...