AcWing 875. 快速幂
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef long long ll;
ll quick_pow(ll a,ll k,ll p){
ll res=1;
while(k){
if(k&1) res=res*a%p;
k>>=1;
a=a*a%p;
}
return res;
}
int main(){
ll a,b,p;
int t;
cin>>t;
while(t--){
cin>>a>>b>>p;
cout<<quick_pow(a,b,p)<<endl;
}
}
AcWing 876. 快速幂求逆元
1.题意:
2.题解:
欧拉公式?a与n互质,aphi(n)恒等于1(mod n)
费马定理,如果p是质数,a与p互质,则an-1恒等于1(mod n),
根据题意逆元即为an-2
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int primes[N];
bool st[N];
int tot;
int phi[N];
typedef long long ll;
ll quick_pow(ll a,ll k,ll p){
ll res=1;
while(k){
if(k&1) res=res*a%p;
k>>=1;
a=a*a%p;
}
return res;
}
void oula(int n){
for(int i=2;i<=n;i++){
if(!st[i]){
primes[tot++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]<=n/i;j++){
st[primes[j]*i]=1;
if(i%primes[j]==0){
phi[primes[j]*i]=primes[j]*phi[i];
break;
}
phi[primes[j]*i]=(primes[j]-1)*phi[i];
}
}
}
int main(){
ll a,p;
int t;
cin>>t;
//oula(100005);
while(t--){
cin>>a>>p;
if(a%p!=0) cout<<quick_pow(a,p-2,p)<<endl;
else cout<<"impossible"<<endl;
}
}
AcWing 877. 扩展欧几里得算法
1.题意:
2.题解:
ax+by=gcd(a,b),对于a和b来说,一定存在正数x,y使得该式子成立,并且gcd是他们能构造的最小的正整数
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void gcd(int a,int b,int &x,int &y){
if(!b){
x=1,y=0;
return;
}
gcd(b,a%b,y,x);
y=y-a/b*x;
}
int main(){
int n,a,b,x,y;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a>>b;
gcd(a,b,x,y);
cout<<x<<" "<<y<<endl;
}
}
AcWing 878. 线性同余方程
1.题意:
2.题解:
扩展欧几里得求线性同余ax恒等于b(mod m),求x
相当于ax-my=b —> ax+my=b;
求a,m的最小公倍数d,如果b是d的倍数,说明存在,否则就不存在,
切记求出的x是一种解,所以要求余m
ax+by=d
通解:x=x0-b/dk
y=y0+a/dk
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
ll gcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll d=gcd(b,a%b,y,x);
y=y-a/b*x;
return d;
}
int main(){
ll n,a,b,m,x,y;
cin>>n;
while(n--){
cin>>a>>b>>m;
// cout<<1<<endl;
ll d=gcd(a,m,x,y);
if(b%d==0){
x=b/d*x%m;//!!注意%m,因为x有可能会爆
cout<<x<<endl;
}else{
cout<<"impossible"<<endl;
}
}
}
AcWing 204. 表达整数的奇怪方式
1.题意:
2.题解:
卡了好久,又是因为没开longlong!!!
中国剩余定理orz,建议再做几遍,感觉还是没懂
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
ll gcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll d=gcd(b,a%b,y,x);
y=y-a/b*x;
return d;
}
ll mod(ll a,ll b){
return (a%b+b)%b;
}
int main(){
ll n,a1,a2;
ll k1,k2,m1,m2;
cin>>n;
cin>>a1>>m1;
for(int i=2;i<=n;i++){
cin>>a2>>m2;
ll d=gcd(a1,-a2,k1,k2);
if((m2-m1)%d==0){
k1=mod(k1*(m2-m1)/d,abs(a2/d));
m1=k1*a1+m1;
a1=abs(a1/d*a2);
}else{
cout<<-1<<endl;
return 0;
}
}
cout<<m1<<endl;
}
AcWing 883. 高斯消元解线性方程组
1.题意:
2.题解:
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const double eps=1e-6;
int n;
double a[110][110];
int guass(){
int c=0,r=0;
for(c=0,r=0;c<n;c++){
int t=r;
for(int i=r;i<n;i++){
if(fabs(a[i][c])>fabs(a[t][c])) t=i;
}
if(fabs(a[t][c])<eps) continue;
for(int i=c;i<=n;i++) swap(a[r][i],a[t][i]);
for(int i=n;i>=c;i--){
a[r][i]/=a[r][c];
}
for(int i=r+1;i<n;i++){
if(fabs(a[i][c])>eps)
for(int j=n;j>=c;j--){
a[i][j]-=a[r][j]*a[i][c];
}
}
r++;
}
if(r<n){
for(int i=r;i<n;i++){
if(fabs(a[i][n])>eps) return 0;//无解
}
return 1;//无穷解
}
for(int i=n-1;i>=0;i--){
for(int j=i+1;j<n;j++){
a[i][n]-=a[i][j]*a[j][n];
}
}
// for(int i=0;i<n;i++){
// for(int j=0;j<=n;j++){
// cout<<a[i][j]<<" ";
// }
// cout<<endl;
// }
return 2;//唯一解
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<=n;j++){
cin>>a[i][j];
}
}
int t=guass();
if(t==1){
cout<<"Infinite group solutions"<<endl;
}else if(t==0){
cout<<"No solution"<<endl;
}else if(t==2){
for(int i=0;i<n;i++){
printf("%.2lf\n",a[i][n]);
}
}
}
AcWing 884. 高斯消元解异或线性方程组
1.题意:
2.题解:
异或==没有进位的加法,可以高斯消元,只有0/1,不是减法,而是异或
3.ac代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;
typedef long long ll;
int a[110][110];
int n;
int gauss(){
int c,r;
for(c=0,r=0;c<n;c++){
int t=r;
if(a[t][c]==0)
for(int i=r;i<n;i++){
if(a[i][c]>a[t][c]){
for(int j=c;j<=n;j++) swap(a[i][j],a[t][j]);
break;
}
}
if(a[t][c]==0) continue;
for(int i=r+1;i<n;i++){
if(a[i][c]==1){
for(int j=c;j<=n;j++) a[i][j]=a[i][j]^a[r][j];//建议倒叙!!
}
}
r++;
}
if(r<n){
for(int i=r;i<n;i++){//!!注意从r开始!!
if(a[i][n]>0) return 0;
}
return 1;
}
for(int i=n-1;i>=0;i--){
for(int j=i+1;j<n;j++){
if(a[i][j]==1)
a[i][n]=a[i][n]^a[j][n];
}
}
// for(int i=0;i<n;i++){
// for(int j=0;j<=n;j++){
// cout<<a[i][j]<<" ";
// }
// cout<<endl;
// }
return 2;
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<=n;j++){
cin>>a[i][j];
}
}
int t=gauss();
if(t==0){
cout<<"No solution"<<endl;
}else if(t==1){
cout<<"Multiple sets of solutions"<<endl;
}else{
for(int i=0;i<n;i++){
cout<<a[i][n]<<endl;
}
}
}