BZOJ-2186 沙拉公主的困惑 线性筛(筛筛筛)+线性推逆元
2016-02-19 18:52
387 查看
2186: [Sdoi2008]沙拉公主的困惑
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 2417 Solved: 803
[Submit][Status][Discuss]
Description
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
Input
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n
Output
共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值
Sample Input
1 11
4 2
Sample Output
1
数据范围:
对于100%的数据,1 < = N , M < = 10000000
HINT
Source
显然答案为:
于是线性筛出质数,线性推出阶乘,再线性处理处 累乘,最后线性推出逆元;
模p意义下逆元线性推法:(inv[1]=1;) inv[i]=(p-p/i)*inv[p%i]%p;
code:
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 2417 Solved: 803
[Submit][Status][Discuss]
Description
大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行编号与M!互质的钞票。房地产第一大户沙拉公主决定预测一下大富翁国现在所有真钞票的数量。现在,请你帮助沙拉公主解决这个问题,由于可能张数非常大,你只需计算出对R取模后的答案即可。R是一个质数。
Input
第一行为两个整数T,R。R<=10^9+10,T<=10000,表示该组中测试数据数目,R为模后面T行,每行一对整数N,M,见题目描述 m<=n
Output
共T行,对于每一对N,M,输出1至N!中与M!素质的数的数量对R取模后的值
Sample Input
1 11
4 2
Sample Output
1
数据范围:
对于100%的数据,1 < = N , M < = 10000000
HINT
Source
显然答案为:
于是线性筛出质数,线性推出阶乘,再线性处理处 累乘,最后线性推出逆元;
模p意义下逆元线性推法:(inv[1]=1;) inv[i]=(p-p/i)*inv[p%i]%p;
一开始我好像在BZOJ上被卡常了?
code:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int n,m,t,p; int read() { int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } #define maxn 10000010 int prime[1000001]; bool flag[maxn]={0}; long long inv[maxn]; long long jc[maxn]; long long ans[maxn]; int quick_pow(long long a,int b,int p) { int ans=1; for(int i=b;i;i>>=1,a=(a*a)%p) if(i&1)ans=(ans*a)%p; return ans; } void get() { memset(flag,0,sizeof(flag)); flag[1]=1; inv[1]=1;jc[1]=1; int cnt=0; for (int i=2; i<=maxn; i++) { jc[i]=jc[i-1]*i%p; if (i<p) inv[i]=(long long)(p-p/i)*inv[p%i]%p; if (!flag[i]) prime[++cnt]=i; for (int j=1; j<=cnt && i*prime[j]<=maxn; j++) { flag[i*prime[j]]=1; if (i%prime[j]==0) break; } } ans[1]=1; for (int i=2; i<=maxn; i++) if (!flag[i]) ans[i]=ans[i-1]*(i-1)%p*inv[i%p]%p; else ans[i]=ans[i-1]; } int main() { t=read(),p=read(); get(); while (t--) { n=read(),m=read(); printf("%d\n",ans[m]*jc %p); } return 0; }
相关文章推荐
- CDZSC_2016寒假个人赛(2)-L(模拟)
- NodeJS 、Express4.x、Augular、Bootstrap项目创建
- [BZOJ 2287][POJ Challenge]消失之物
- POJ 1426 Find The Multiple
- BZOJ-2186 沙拉公主的困惑 线性筛(筛筛筛)+线性推逆元
- [Locked] Sparse Matrix Multiplication
- 3列、2列自适应布局,中部内容优先显示3列布局等方法
- 神奇的计算器dc和bc
- BZOJ3591: 最长上升子序列
- 讲讲移动测试的流程
- 安装中文CentOS 6.5的详细步骤
- ACM数论之旅11---浅谈指数与对数(长篇)(今天休息,不学太难的数论> 3<)
- iOS OC内存管理、ARC、property属性、__strong、__weak、__block——iOS 编码复习(一)
- Android中AsyncTask使用详解
- ZOJ-2971-Give Me the Number【5th浙江省赛】
- LinSSID:图形化的wifi扫描器在GNU Linux(Debian系)下的安装
- 三层总结
- leetcode笔记--Insertion Sort List
- 【BZOJ 1013】【JSOI2008】球形空间产生器sphere 高斯消元基础题
- 火狐表格错乱兼容性问题