2021-10-06

反素数

首先,该题数据范围较大, 1 0 9 10^9 109,因此不能朴素枚举,又因为相当于是求围内约数最多的数,可以想到: n = 2 a × 3 b … … n=2^a \times 3^b…… n=2a×3b
然后就可以直接枚,最多也就枚到23就ok了,但是注意
另一种思路:
打表,咳咳,其实是认真的,因为只有前几个素数,范围较小,所以就直接打前几个反素数,然后观察规律,就可以发现是以差的倍数增加的,就可以先打小表再打大表:

#include <bits/stdc++.h>
#define ll long long
#define N 100
using namespace std;
ll n,ans;
int a[N]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,221760,277200,332640,498960,554400,665280,720720,1081080,1441440,2162160,2882880,3603600,4324320,6486480,7207200,8648640,10810800,14414400,17297280,21621600,32432400,36756720,43243200,61261200,73513440,110270160,122522400,147026880,183783600,245044800,294053760,367567200,551350800,698377680,735134400,1102701600,1396755360};
int main()
{
	scanf("%d",&n);
	for(int i=N-1;i>=0;i--)
	{
		if(a[i]&&a[i]<n)
		{
			printf("%d\n",a[i]);
			break;
		}
	}
	return 0;
}

五指山

一看就知道是同余问题,所以反手打出exgcd的版,
不会扩展欧几里得的点这儿
后面判断一下就好了

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll T,a,b,x,y;
ll exgcd(ll a, ll b, ll & x, ll & y)
{
	if (!b){
		x = 1;
		y = 0;
		return a;
	}
	ll d = exgcd(b, a % b, y, x);
	y -= a / b*x;
	return d;
}
int main(){
	scanf("%d",&T);
	while(T--){
		ll a,b,x,y,p,q;
		scanf("%d%d%d%d",&b,&a,&x,&y);
		ll g=exgcd(b,a,q,p);
		if((y-x)%g){
			printf("Impossible\n");
			continue;
		}
		p*=(y-x)/g;
		b/=g;
		ll ans=(p%b+b)%b;
		printf("%lld\n",ans);
	}
	return 0;
}

Xiao 9*大战朱最学

yes,模板题,中国剩余定理,然后就可以(也是exgcd
直接干就完事

#include<bits/stdc++.h>
#define N 15
#define ll long long
using namespace std;
ll a[N], b[N];
ll M[N], k[N];
ll exgcd(ll a, ll b, ll& x, ll& y)
{
	ll d = a;
	if (!b){
		x = 1,y = 0;
		return a;
	}
	d = exgcd(b, a % b, y, x);
	y -= (a / b) * x;
	return d;
}

int main()
{
	int n;
	ll x, y, ans = 0, mod = 1;
	cin >> n;
	for (int i = 1; i <= n; i++){
		cin >> a[i] >> b[i];
		mod *= a[i]; 
	}
	for (int i = 1; i <= n; i++){
		M[i]=mod/a[i];
		exgcd(M[i],a[i],x,y);
		k[i] = (a[i] + x % a[i]) % a[i];//保证x为正数 
		ans = (ans + b[i] * k[i] * M[i]) % mod;
	}
	printf("%lld",ans);
	return 0;
}

Goldbach’s Conjecture

这属于是很难很难啊,都还没证明呢水题了,刚开始想暴力的然后……
算了,暴力不优雅。
就先预处理后直接从小往大枚,然后就没事了
写个primes的代码练练手就好了

void pre(LL n){
	memset(v,0,sizeof(v));
	m=0;
	for(LL i=2; i<=n; i++) {
		if(v[i]==0) {
			v[i]=i;
			prime[++m]=i;
		}
		for(LL j=1; j<=m; j++) {
			if(prime[j]>v[i] || prime[j]>n/i)break;
			v[i*prime[j]]=prime[j];
		}
	}
//	for(int i=1;i<=m;i++)printf("%d\n",prime[i]);
}

溜了溜了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值