费马小定理(Fermat’s little theorem)是数论中的一个重要定理,在1636年提出。如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。
首先理解一下费马小定理
p是个质数 ,a不能是p的倍数 就满足a^(p-1)≡1(mod p)
公式是(nn-m)/(nn)=1-m/(nn)
(1-m/(nn))mod(M)=1-m mod(M)((nn)^(-1)mod(M)) mod(M)
而(nn)^(-1)mod(M)=(nn) ^ (M-2)mod(M)
所以敲一个快速幂就好了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int Mod=998244353;
ll fun(ll a,ll b){
ll res=1;
a%=Mod;
while(b){
if(b&1)res=res*a%Mod;
b>>=1;
a=a*a%Mod;
}
return res;
}
int main(){
ll n,m;
cin>>n>>m;
ll a=m,b=n*n;
ll ans=1-a*fun(b,Mod-2)%Mod;
ans=(ans%Mod+Mod)%Mod;
cout<<ans;
return 0;
}
先把这张图扒下来
侵删
边刷着课边刷杭电oj
快速幂要多敲几遍
ll fun(ll a,ll b,ll p){
ll x=1;
a%=p;
while(b){
if(b&1)x=x*a%p;
b>>=1;
a=a*a%p;
}
return x;
}
04年的浙江CPC
很有味道
这题首先求各个针的速度
1、秒针是6°/s 分针是 1/10°/s 时针是 1/120°/s
注意我们的时钟是12小时的。。。
所以我们一天86400s
在本题中可以只算半天,即43200s
2、那我们来到了下一步----计算三针速度差
秒时针速度差 sh=719/120°/s
分时针速度差 mh=11/120°/s
秒分针速度差 sm=59/10°/s
3、计算周期
周期即两针从开始满足条件到结束满足条件的时间
计算出第一次的开始满足时间和结束满足时间
即D/sh D/mh D/sm
和(360-D)/sh (360-D)/mh (360-D)/sm
接着穷举两针时间
判断区间是否合理
直到到达43200.000001
为啥要用0.000001呢?
因为double有时候会抽
无缘无故多那么0.000001
如果不加0.000001
本来可以加到43200的,结果因为多了0.000001而加不到了
所以这个0.000001很重要
以后写double的时候一定要注意
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
// 秒针速度 s = 6°/s 分针速度 m = 1/10° /s 时针 h = 1/120° /s
const double SH = 719.0/120, SM = 59.0/10, MH = 11.0/120;
const double tSH = 43200.0/719, tSM = 3600.0/59, tMH = 43200.0/11;
double Min(double a,double b,double c)
{
return min(a,min(b,c));
}
double Max(double a,double b,double c)
{
return max(a,max(b,c));
}
int main()
{
double D;
while(cin >> D && D!=-1)
{
double bSH,bSM,bMH,eSH,eSM,eMH,Begin,End,Sum = 0;
bSH = D / SH;
bSM = D / SM;
bMH = D / MH;
//计算第一次满足条件的时间(开始时间)
eSH = (360-D)/SH;
eSM = (360-D)/SM;
eMH = (360-D)/MH;
double b1,b2,b3,e1,e2,e3;
//计算第一次不满足条件的时间(结束时间)
for(b3 = bSH,e3 = eSH; e3 <= 43200; b3+=tSH,e3+=tSH)
{
for(b2 = bMH,e2 = eMH; e2 <= 43200; b2+=tMH,e2+=tMH)
{
if(e2 < b3) //判断是否有交集
continue;
if(b2 > e3)
break;
for(b1 = bSM,e1 = eSM; e1 <= 43200; b1+=tSM,e1+=tSM)
{
if(e1 < b2 || e1 < b3)
continue;
if(b1 > e2 || b1 > e3)
break;
Begin = Max(b1,b2,b3); //开始时间取最大,以满足全部要求
End = Min(e1,e2,e3); //结束时间取最小,以满足全部要求
Sum += (End-Begin);
//cout<<(End-Begin)<<endl;
}
}
}
printf("%.3lf\n",Sum/432);
//cout<<b1<<" "<<b2<<" "<<b3<<" "<<e1<<" "<<e2<<" "<<e3;
}
return 0;
}
今儿就到这