1.欧几里得拓展及应用
拓展欧几里得就是求形如ax+by=gcd(a,b)的解,应用可以求ax+by=c二元一次方程组的解;如果c是gcd(a,b)的倍数才有解
1.
temp=x;
x=y;
y=temp-(b/a)*y;
2.
x=x0*(c/gcd);
t=x/(b/gcd);
x=x-t*(b/gcd);
if(x<0)x=x+b/gcd;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x,y,m,n,l;//欧几里得tuozhan
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;y=0;return a;
}
ll g=ex_gcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-(a/b)*y;
return g;
}
int main()
{
cin>>x>>y>>m>>n>>l;//(m-n)t=(y-x)+kL;
ll a=m-n,b=l,c=y-x;
if(m-n<0)
{
a=-a;c=-c;
}
ll x0,y0;
ll gcd=ex_gcd(a,b,x0,y0);
if(c%gcd!=0)
{
cout<<"Imposible"<<endl;return 0;
}
ll ans;
ans=x0*(c/gcd);
ll t=ans/(b/gcd);
ans=ans-t*(b/gcd);
if(ans<=0)ans+=b/gcd;
cout<<ans<<endl;
return 0;
}
2.连续素数和
用的是前缀和+二分查找
用到了欧拉筛素数
注意long long
#include<bits/stdc++.h>
using namespace std;
int t;
int k=0,ans=0;
const int maxn=4e7+10;
int prime[maxn];
int mark[maxn];
long long sum[maxn];
void pinit()
{
mark[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!mark[i])prime[++k]=i;
for(int j=1;j<=k&&prime[j]*i<=maxn;j++)
{
mark[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
return ;
}
void zhihe()
{
for(int i=1;i<=k;i++)
{
sum[i]=sum[i-1]+prime[i];
}
}
bool find(int l,int r,long long x)
{
while(l<=r)
{
int mid=(l+r)/2;
if(sum[mid]==x)return true;
else if(sum[mid]>x)r=mid-1;
else l=mid+1;
}
return 0;
}
int main()
{
cin>>t;
pinit();
zhihe();sum[0]=0;
while(t--)
{
ans=0;
int n;
cin>>n;
int i=0;
while(1)
{
i++;if(sum[i]>=n)break;
}
for(int j=i;prime[j]<=n;j++)
{
long long x=sum[j]-n;
if(find(0,j,x))
ans++;
}
cout<<ans<<endl;
}
return 0;
}
3.prime distance
这道题要用到区间素数筛,由于l,r很大,但是r-l却不大
除了用欧拉筛开辟bool vis[50000],prime[50000]两个数组外还开一个bool temp[maxn]和ans[maxn]
temp用来表示l到r区间内的数是否为素数,ans用来记录l到r之间的素数;一般int范围内的数开到根号下2147483647;
vis
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,r,l;
const int maxn=1e6+10;
const int N=5e4;
bool vis[N],temp[maxn];
int prime[N],ans[maxn];
int cnt,cntt;
void init()
{
memset(vis,0,sizeof(vis));
cnt=0;
for(int i=2;i<=N;i++)
{
if(!vis[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&prime[j]*i<=N;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)break;
}
}
}
void prim_e()
{
memset(temp,0,sizeof(temp));
for(int i=1;i<=cnt;i++)
{
int b=l/prime[i];
while(b<=1)b++;
for(int j=b*prime[i];j<=r;j+=prime[i])
{
if(l<=j)
temp[j-l+1]=1;
}
}
if(l==1)temp[1]=1;
for(int i=1;i<=r-l+1;i++)
{
if(!temp[i])ans[++cntt]=i+l-1;
}
}
int main()
{
cin>>t;
init();
while(t--)
{
cntt=0;
cin>>l>>r;
prim_e();
int minp=2,maxp=2;
if(cntt<=1)cout<<"There are no adjacent primes."<<endl;
else
{
for(int i=2;i<=cntt;i++)
{
int d=ans[i]-ans[i-1];
if(d<ans[minp]-ans[minp-1])minp=i;
if(d>ans[maxp]-ans[maxp-1])maxp=i;
}
cout<<ans[minp-1]<<","<<ans[minp]<<" are closest, ";
cout<<ans[maxp-1]<<","<<ans[maxp]<<" are most distant."<<endl;
}
}
return 0;
}
4.prime land
我是直接模拟出来的,不过题目中这个公式挺重要的
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
int t,k;
int n,cnt;
bool vis[maxn];
int prime[maxn];
int p[maxn],e[maxn];
int qiun()
{
int n=1;
for(int i=1;i<=k;i++)
n=n*pow(p[i],e[i]);
return n-1;
}
void prim_e()
{
cnt=0;
memset(vis,0,sizeof(vis));
vis[1]=1;
for(int i=2;i<=maxn;i++)
{
if(!vis[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&prime[j]*i<=maxn;j++)
{
vis[prime[j]*i]=1;
if(!i%prime[j])break;
}
}
}
void answer(int y)
{
if(!vis[y])
{
cout<<y<<" "<<1<<endl;
return ;
}
int i=1;
while(prime[i]<y)
i++;//找到最大的那个
for(int j=i;y!=1&&j>=1;j--)
{
int e=0;
while(y%prime[j]==0)
{
y=y/prime[j];
e++;
}
if(e)
cout<<prime[j]<<" "<<e<<" ";
}
cout<<endl;
}
int main()
{
cin>>t;
prim_e();
while(t--)
{
cin>>k;
for(int i=1;i<=k;i++)
cin>>p[i]>>e[i];
int u=qiun();
answer(u);
}
return 0;
}
5.x-factor
找到题目的本质是求一个数的最大质因子个数第二个是求所有质因子全排列,注意要去掉重复的情况;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map <int,int> prim_factor(ll n2) {
map<int,int> maps;
int N = n2;
for(int i=2;i*i<=N;i++) {
while(n2 % i == 0) {
maps[i]++;
n2 /= i;
}
}
if(n2 > 1)
maps[n2]++;
return maps;
};
ll mult(int k) {
ll ans = 1;
for(int i=2;i<=k;i++)
ans *= i;
return ans;
}
int main() {
ll n;int t;cin>>t;
while(t--) {
cin>>n;
map <int,int> :: iterator iter;
map <int,int> maps = prim_factor(n);
int len = 0;
for(iter=maps.begin();iter!=maps.end();iter++)
len += iter->second;
ll ans = mult(len);
for(iter=maps.begin();iter!=maps.end();iter++)
ans /= mult(iter->second);
printf("%d %lld\n",len,ans);
}
return 0;
}