[JZOJ6272] 2019.8.4【NOIP提高组A】整除
题目
题目大意
求方程\((x^m-x)\mod n=0\)在整数范围\([1,n]\)的解的个数。
\(n=\sum_{i=1}^{c}p_i\)
给出\(c\)和\(p_i\)
思考历程
作为数论白痴,比赛时看到这题就想要自闭了……
乱推一波式子,后面的就不会搞了。
于是就想部分分……结果连部分分都没有想出来。
直接打了个\(20\)分的暴力。
正解
可以把方程拆成\(c\)个方程(对于每个\(i\)):\((x^m-x)\mod p_i=0\)
分别解出每个同余方程组。解的时候枚举\(x\),并将每个\(x^m\)处理出来。
快速幂会TLE,所以要用积性筛的方式来求\(x^m\)。具体来说,函数\(f(x)=x^m\)是个积性函数。所以用快速幂求出\(x\)为质数时的\(x^m\),合数就是两个因数的函数值乘起来。
这样时间复杂度是可以过的。
处理出来之后,每个同余方程的解的个数的乘积就是整个同余方程组的解的个数。
证明;
对于方程\((x^m-x)\mod p_i=0\),设解为\(x_{i,1},x_{i,2},...,x_{i,s_i}\)
每个方程分别抽出一个解来,记作\(x_i\),\(x_i\)为\(x_{i,1..s_i}\)中的一个解。
设方程组的解为\(X\)
那么这个\(X\)满足以下方程组(对于每个\(i\)):
\(X \equiv x_i (\mod p_i)\)
根据中国剩余定理,这个方程组只会有一个解。
方程组的解和\(x_1,x_2,..,x_c\)的取值是一一对应的(这个可以感性理解)。
对于\(x_i\),有\(s_i\)种可能的取值。根据乘法原理,同余方程组解的个数即为每个同余方程的解的个数的乘积。
后来我知道了一个更加强大的方法。
同样是求\((x^m-x)\mod p_i=0\)的解的个数,然而这次不用暴力求。
有个性质:解的个数等于\(\gcd(m-1,p_i-1)+1\)
(为了方便,后面直接将\(p_i\)的下标省略。)
证明:
原式可以写成\(x^m\equiv x(\mod p)\)
\(p=2\)的时候显然成立。
\(x=0\)显然是方程的解
考虑解在区间\([1,p-1]\)的取值
由于\(p\)为奇素数,所以一定有原根。设原根为\(g\)
方程可以表示为\(g^{ym}\equiv g^y (\mod p)\)
由费马小定理得\(ym\equiv y (\mod (p-1))\)
也就是\(y(m-1) \equiv 0 (\mod (p-1))\)
设\(k=\gcd(m-1,p-1)\)。两边同时除以\(k\)得\(y\frac{m-1}{k}\equiv 0 (\mod \frac{p-1}{k})\)
由于\(\gcd(\frac{m-1}{k},\frac{p-1}{k})=1\),所以\(\frac{p-1}{k}|y\)
所以\(y\)为\(\frac{p-1}{k}\)的倍数,显然可以取\(0\)到\(k-1\)倍,也就是说\(y\)有\(k\)个解。
所以\(x\)也有\(k\)个解。
所以解的个数为\(\gcd(m-1,p_i-1)+1\)
有了这条性质,程序就快得飞起了(爆踩标程)……
代码
暴力求解:
(反正数据范围这么小,就懒得打线筛了。埃氏筛法的常数小一些)
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mo 998244353
#define P 10000
int id;
int c,m;
int n;
inline int my_pow(int x,int y,int p){
int res=1;
for (;y && res;y>>=1,x=x*x%p)
if (y&1)
res=res*x%p;
return res;
}
int di[P+1];
int xm[P+1];
inline void init(){
di[1]=1;
for (register int i=2;i<=P;++i){
if (di[i])
continue;
di[i]=i;
for (int j=i*i;j<=P;j+=i)
di[j]=i;
}
}
inline int work(int p){
int res=2;
xm[0]=0,xm[1]=1;
for (register int i=2;i<=p;++i){
xm[i]=(di[i]==i?my_pow(i,m,p):xm[i/di[i]]*xm[di[i]]%p);
res+=(xm[i]==i);
}
return res;
}
int main(){
freopen("division.in","r",stdin);
freopen("division.out","w",stdout);
int T;
scanf("%d%d",&id,&T);
init();
while (T--){
scanf("%d%d",&c,&m);
long long ans=1;
for (int i=1;i<=c;++i){
int p;
scanf("%d",&p);
ans=ans*work(p)%mo;
}
printf("%lld\n",ans);
}
return 0;
}
牛逼解法:
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mo 998244353
inline int gcd(int a,int b){
int k;
while (b){
k=a%b;
a=b;
b=k;
}
return a;
}
int main(){
freopen("division.in","r",stdin);
freopen("division.out","w",stdout);
int T;
scanf("%*d%d",&T);
while (T--){
int c,m;
scanf("%d%d",&c,&m);
long long ans=1;
while (c--){
int p;
scanf("%d",&p);
ans=ans*(gcd(p-1,m-1)+1)%mo;
}
printf("%lld\n",ans);
}
return 0;
}
总结
看来我的数论还是太菜了……QWQ……
[JZOJ6272] 2019.8.4【NOIP提高组A】整除的更多相关文章
- NOIP提高组2004 合并果子题解
NOIP提高组2004 合并果子题解 描述:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消 ...
- 计蒜客 NOIP 提高组模拟竞赛第一试 补记
计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...
- 1043 方格取数 2000 noip 提高组
1043 方格取数 2000 noip 提高组 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样 ...
- [NOIP提高组2018]货币系统
[TOC] 题目名称:货币系统 来源:2018年NOIP提高组 链接 博客链接 CSDN 洛谷博客 洛谷题解 题目链接 LibreOJ(2951) 洛谷(P5020) 大视野在线评测(1425) 题目 ...
- NOIP提高组初赛难题总结
NOIP提高组初赛难题总结 注:笔者开始写本文章时noip初赛新题型还未公布,故会含有一些比较老的内容,敬请谅解. 约定: 若无特殊说明,本文中未知数均为整数 [表达式] 表示:在表达式成立时它的值为 ...
- 津津的储蓄计划 NOIp提高组2004
这个题目当年困扰了我许久,现在来反思一下 本文为博客园ShyButHandsome的原创作品,转载请注明出处 右边有目录,方便快速浏览 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津\ ...
- 2018.12.30【NOIP提高组】模拟赛C组总结
2018.12.30[NOIP提高组]模拟赛C组总结 今天成功回归开始做比赛 感觉十分良(zhōng)好(chà). 统计数字(count.pas/c/cpp) 字符串的展开(expand.pas/c ...
- 2018.12.08【NOIP提高组】模拟B组总结(未完成)
2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...
- 2013 Noip提高组 Day2
3288积木大赛 正文 题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前 ...
- 2013 Noip提高组 Day1
3285 转圈游戏 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description ...
随机推荐
- BBS论坛 登录功能
四.登录功能 前端页面html代码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- minicom 的使用
1.切换到 root 用户. [root@localhost btools]#su - 2. 查找有效的串设备. [root@localhost ~]#cat /proc/devices ... 4 ...
- 在Nginx/Tengine服务器上安装证书
可以从SSL证书服务控制台下载证书安装到Nginx/Tengine服务器上. 环境:以CentOS 7.Nginx 1.15.6为例. 证书名称以domain name为示例,如证书文件名称为doma ...
- zeromq protobuf例子
https://github.com/AifiHenryMa/zeromq_protocolbuffer_demo https://github.com/protocolbuffers/protobu ...
- vue之vue-router嵌套路由
1.定义路由 routes: [ { path: '/product', //第一层路由 name: 'product', component: Vproductcontent,//父组件渲染的是子组 ...
- WindowsPowerShell常用命令
zai 获得Shell权限之后,可使用如下命令对系统进行文件操作: cd 后跟相应参数: cd ../ 返回上一级目录 cd +路径 跳转至制定目录(如果路径存在且正确的话) type flag.tx ...
- redis数据备份还原
安装ruby yum install ruby rubygems ruby-devel -y 安装rvm gpg2 --keyserver hkp://pool.sks-keyservers.net ...
- Python自学:第四章 切片
# -*- coding: GBK -*- players = ['charles', 'martina', 'michael', 'florence', 'eli'] print(players[0 ...
- MySQL主从复制&读写分离&分库分表
MySQL主从复制 MySQL的主从复制只能保证主机对外提供服务,从机是不提供服务的,只是在后台为主机进行备份数据 首先我们说说主从复制的原理,这个是必须要理解的玩意儿: 理解: MySQL之间的数据 ...
- NX二次开发-UFUN初始化UF_initialize
在调用UFUN函数时必须加Uf.h头文件,代码开头和结尾加UF_initialize和UF_terminate NX9+VS2012 #include <uf.h> #include &l ...