标签:rr dsy int res Day4 Vacation Trainning include ll
沙拉公主的困惑
不难发现与 m! 互质的数在 [m+1,n!] 中产生,这些数实则可以表示为 p*m!+q(\(0\leq q\leq m-1\))。
q 与 m 互质,那么答案就是 \(\frac{n!}{m!}\phi(m!)\) 了。
对于前一部分,因为阶乘在中途可能会变为0,所以直接用 zkw 线段树维护区间乘积。
至于后一部分,根据欧拉函数的求法,枚举i=1~m,若 i 为质数,产生贡献就是 i-1,否则肯定分解成之前的质数乘积,贡献直接就是 i 了。
也就是可以线性求阶乘的欧拉函数。
挺有趣哈(虽然听了 lihan 聚聚的提示)。
Code:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const int MAXN=1e7;
const int MAXP=1e7;
int cnt,p;
int T,r,n,m,pp[MAXP+5],phi[MAXN+5],dsy[(MAXN<<2)+5];
bool vis[MAXN+5];
void Ola(){
vis[0]=vis[1]=1;
phi[1]=1;
for(int i=2;i<=MAXN;i++){
if(!vis[i]){
pp[++cnt]=i;
}
for(int j=1;j<=cnt&&pp[j]<=MAXN/i;j++){
vis[i*pp[j]]=1;
if(i%pp[j]==0){
break;
}
}
}
}
void bui(){
p=1;
while(p<MAXN+2) p<<=1;
for(int i=1;i<=MAXN;i++){
dsy[i+p]=i;
}
for(int i=p+MAXN+1;i>1;i--){
dsy[i>>1]=((ll)dsy[i>>1]*dsy[i])%r;
}
}
ll Sum(int l,int rr){
l=l+p-1,rr=rr+p+1;ll res=1;
for(;(l^rr)!=1;l>>=1,rr>>=1){
if(!(l&1)) res=(res*(ll)dsy[l^1])%r;
if(rr&1) res=(res*(ll)dsy[rr^1])%r;
}
return res;
}
int main(){
scanf("%d%d",&T,&r);
for(int i=0;i<(MAXN<<2)+5;i++) dsy[i]=1;
Ola();
for(int i=2;i<=MAXN;i++){
if(!vis[i]) phi[i]=(ll)phi[i-1]*(i-1)%r;
else phi[i]=(ll)phi[i-1]*i%r;
}
bui();
while(T--){
scanf("%d%d",&n,&m);
ll tmp=Sum(m+1,n),res=(ll)phi[m];
printf("%lld\n",res*tmp%r);
}
return 0;
}
标签:rr,dsy,int,res,Day4,Vacation,Trainning,include,ll
来源: https://www.cnblogs.com/StranGePants/p/16467828.html
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。