NOIP数学相关模板整理

$O(n)$递推求逆元

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int inv[3000010];
 7 int main(){
 8     int n,p;
 9     scanf("%d%d",&n,&p);
10     inv[1]=1;
11     printf("1\n");
12     for(int i=2;i<=n;i++){
13         inv[i]=(ll)(p-p/i)*inv[p%i]%p;
14         printf("%d\n",inv[i]);
15     }
16     return 0;
17 }

 

exgcd求逆元

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 void exgcd(int a,int b,int &x,int &y){
 6     if(!b){
 7         x=1;
 8         y=0;
 9         return;
10     }
11     exgcd(b,a%b,x,y);
12     int tmp=x;
13     x=y;
14     y=tmp-a/b*y;
15 }
16 int main(){
17     int a,b;
18     scanf("%d%d",&a,&b);
19     int x,y;
20     exgcd(a,b,x,y);
21     x=(x%b+b)%b;
22     printf("%d\n",x);
23     return 0;
24 }

 

模数为质数时,用费马小定理求逆元

 1 #include<cstdio>
 2 typedef long long ll;
 3 const int mod=1e9+7;
 4 ll ksm(ll x,ll y){
 5     ll ret=1;
 6     while(y){
 7         if(y&1) ret=ret*x%mod;
 8         x=x*x%mod;
 9         y>>=1;
10     }
11     return ret;
12 }
13 int main(){
14     ll a;
15     scanf("%lld",&a);
16     printf("%lld",ksm(a,mod-2));
17     return 0;
18 }

 

$O(n)$求$1!$到$N!$的逆元

$1/i!=(i+1)/(i+1)!$

实现时先求出$f[n]$再反向递推

1 f[i]=(ll)(i+1)*f[i+1]%mod

 

中国剩余定理

贴一篇别人的:http://www.cnblogs.com/MashiroSky/p/5918158.html

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int N,A[15],B[15];
 7 void Exgcd(ll a,ll b,ll &x,ll &y){
 8     if(!b){
 9         x=1;
10         y=0;
11         return;
12     }
13     Exgcd(b,a%b,x,y);
14     ll tmp=x;
15     x=y;
16     y=tmp-a/b*y;
17 }
18 ll Chinese_Remainder_Theorem(){
19     ll M=1;
20     for(int i=1;i<=N;i++) M*=A[i];
21     ll ret=0,x,y;
22     for(int i=1;i<=N;i++){
23         ll tmp=M/A[i];
24         Exgcd(tmp,A[i],x,y);
25         ret=(ret+tmp*x*B[i])%M;
26     }
27     return (ret+M)%M;
28 }
29 int main(){
30     return 0;
31 }

 

Lucas定理

$C(N,M)\% P = C(N\% P,M\% P) * C(N/P,M/P)\% P$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int N,M,P;
 7 int inv[100010],fac[100010];
 8 int C(int x,int y){
 9     if(x<y) return 0;
10     return (ll)fac[x]*inv[fac[y]]%P*inv[fac[x-y]]%P;
11 }
12 int Lucas(){
13     if(N<M) return 0;
14     ll ret=1;
15     while(M){
16         ret=ret*C(N%P,M%P)%P;
17         N/=P;
18         M/=P;
19     }
20     return ret;
21 }
22 int main(){
23     int Test;
24     scanf("%d",&Test);
25     while(Test--){
26         scanf("%d%d%d",&N,&M,&P);
27         swap(N,M);
28         N+=M;
29         inv[1]=1;for(int i=2;i<P;i++) inv[i]=(ll)(P-P/i)*inv[P%i]%P;
30         fac[0]=1;for(int i=1;i<=N;i++) fac[i]=(ll)fac[i-1]*i%P;
31         printf("%d\n",Lucas());
32     }
33     return 0;
34 }

 

高斯消元

最后回代求解的时候,若发现某一项元系数为零,且式子右边常数为零,则有无数多个解,若常数不为零,则无解。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 int inline readint(){
 7     int Num=0,Flag=1;char ch;
 8     while((ch=getchar())<'0'||ch>'9') if(ch=='-') break;
 9     if(ch=='-') Flag=-1; else Num=ch-'0';
10     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
11     return Num*Flag;
12 }
13 int N;
14 double A[110][110];
15 bool Gauss(){
16     int t;
17     for(int i=1;i<=N;i++){
18         t=i;
19         for(int j=i+1;j<=N;j++)
20             if(fabs(A[j][i])>fabs(A[t][i]))
21                 t=j;
22         if(t!=i)
23             for(int j=i;j<=N+1;j++)
24                 swap(A[t][j],A[i][j]);
25         for(int j=i+1;j<=N;j++){
26             double r=A[j][i]/A[i][i];
27             for(int k=i;k<=N+1;k++)
28                 A[j][k]-=A[i][k]*r;
29         }
30     }
31     for(int i=N;i>=1;i--){
32         for(int j=i+1;j<=N;j++)
33             A[i][N+1]-=A[i][j]*A[j][N+1];
34         if(A[i][i]==0&&A[i][N+1]==0) return false;
35         A[i][N+1]/=A[i][i];
36     }
37     return true;
38 }
39 int main(){
40     N=readint();
41     for(int i=1;i<=N;i++)
42         for(int j=1;j<=N+1;j++)
43             A[i][j]=readint();
44     if(!Gauss()){
45         puts("No Solution");
46         return 0;
47     }
48     for(int i=1;i<=N;i++) printf("%.2lf\n",A[i][N+1]);
49     return 0;
50 }

 

posted @ 2017-10-30 21:46  halfrot  阅读(391)  评论(0编辑  收藏  举报