トピック
2186:[Sdoi2008]プリンセスサラダの混乱
時間制限:10秒メモリ制限:259 MB
説明
インフレと偽造紙幣の急増により、政府は新しいポリシーの導入を決定しました。既存の紙幣の番号は1からN階乗ですが、政府は相互に素数のある紙幣のみを発行します。最大の不動産所有者であるプリンセスサラダは、独占国家における現在のリアルマネー数を予測することを決定しました。さて、プリンセスサラがこの問題を解決するのを手伝ってくださいシートの数は非常に多いかもしれないので、剰余Rをとった後で答えを計算するだけで済みます。Rは素数です。
入力
最初の行は2つの整数TとRです。R <= 10 ^ 9 + 10、T <= 10000、グループ内のテストデータの数を示します。Rは係数です。
次のT行。各行は整数NとMのペアです。タイトルの説明を参照してくださいm <= n
100%データの場合、1 <= N、M <= 10000000出力
N、Mの各ペアの合計T行は、1からNを出力します。中国とM!Rを法とする質の数の値
入力例
5 1000000007
35434 3244
10000000 1324
2316354 3243354
24223 242
1534234 123432出力例
330733849
347925786
796298408
445433358
152561042
分析
- 問題は、1〜(n!)がm!に比較的素数である数を尋ねることであり、答えはRを法としています。
- この質問は本当にわかりません。このブログの投稿を読むまではわかりませんでした。ここに入力しましょう。
- (http://blog.csdn.net/PoPoQQQ/article/details/39957117)
プログラム
#include <cstdio>
#define N 10000002
typedef int ll;
ll i,j,T,k,Ha,n,m,ans,p[665000],v[N],g[N],h[N],num;
long long ret;
bool f[N];
//v:i的逆元 g:i的阶乘 h:Pi((p[i]-1)/p[i],a[i]<=i)
ll ksm(ll x,ll y){
for (ret=1; y; y>>=1,x=((long long)x*x)%Ha)
if (y&1) ret=(long long)ret*x%Ha;
return ret;
}
void get_p(){
for (g[1]=h[1]=v[1]=1,i=2; i<N; i++){
g[i]=(long long)g[i-1]*i%Ha;
v[i]=(long long)v[Ha%i]*(Ha-(Ha/i))%Ha;
if (!f[i]){
p[++num]=i;
h[i]=(long long)h[i-1]*(i-1)%Ha*v[p[num]%Ha]%Ha;
}else h[i]=h[i-1];
for (j=1; j<=num && (long long)i*p[j]<N; j++){
f[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
int main(){
scanf("%d%d",&T,&Ha);
get_p();
while (T--){
scanf("%d%d",&n,&m);
ans=(long long)h[m]*g[n]%Ha;
printf("%d\n",ans);
}
}
促す
- モジュロの問題は慎重に検討する必要があります。
- 逆元は実際には計算する必要がある1〜Ha-1だけで、他の数値の逆元は次のように表すことができます
1/(i%Ha)
- MLEを初めて支払ったとき...