POJ3292&&2115

这两道题还是比较简单的,没有什么难度

不过归在数论这个专题里我还是比较认同的,多少有些关系

3292

题目大意:给你一个范围n,让你求出这个范围内所有形式类似\(4k+1(k为正整数)\)的数中的H-semi-primes的个数

所谓H-semi-primes,就是在一个由两个H-primes相乘得到的数。其中H-primes就是在这些数范围内的素数。什么意思?就是在所有的形式如上的数中不能由其它这种形式的数相乘得到的。

例如,9就是一个H-primes,虽然它在自然数范围内并不是素数。但是由于在这些形式的数中并没有它的真因数,因此它就是H-primes。

所以我们只需要用一种类似于筛法的东西筛去所有非H-primes,然后就可以得出所有的H-semi-primes。然后累加打表即可

具体看CODE

#include<cstdio>
using namespace std;
const int N=1000005;
int ans[N],n;
bool vis[N];
inline char tc(void)
{
	static char fl[100000],*A=fl,*B=fl;
	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
	x=0; char ch=tc();
	while (ch<'0'||ch>'9') ch=tc();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(int x)
{
	if (x/10) write(x/10);
	putchar(x%10+'0');
}
inline void init(int n)
{
	register int i,j; int tot=0;
	for (i=5;i<n;i+=4)
	for (j=5;j<n;j+=4)
	{
		int m=i*j; if (m>n) break;
		if (!ans[i]&&!ans[j]) ans[m]=1; else ans[m]=-1;
	}
	for (i=1;i<=n;++i)
	{
		if (!(ans[i]^1)) ++tot;
		ans[i]=tot;
	}
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	register int i,j; init(N);
	for (;;)
	{
		read(n); if (!n) break;
		write(n); putchar(' '); write(ans[n]); putchar('\n');
	}
	return 0;
}

2115

这还是一道比较入门的扩欧水题

题目大意:有一个循环形式如题目所说,然后问它在无符号整数(位数为k)的情况下运行的情况。

如果是死循环就输出"FOREVER",否则输出循环步数

这还是很简单的,我们先对题意进行简化。首先我们知道这样的运行越界后其实是自动模\(2^k\) 的,然后我们可以得出方程,其中我们设要操作的次数为\(x\),那么我们要的结果就是\(x\)最小非负整数解

\((A+Cx) \equiv B (mod\ 2^k)\)

然后我们对于这个同余方程可以通过经典的方法来扩欧求解

我们通过\(mod\)的性质可以知道,设\(mod\)操作减去了\(2^ky\)次,即有新的不定方程

\(A+Cx-2^ky=B\)

移项后为:

\(Cx-2^ky=B-A\)

然后我们直接套扩欧的板子即可,这里注意有解的必要条件为\(gcd(C,2^k)\mid B-A\)

CODE

#include<cstdio>
using namespace std;
typedef long long LL;
LL A,B,C,K,a,b,c,d,x,y;
inline char tc(void)
{
	static char fl[100000],*A=fl,*B=fl;
	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(LL &x)
{
	x=0; char ch=tc();
	while (ch<'0'||ch>'9') ch=tc();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void write(LL x)
{
	if (x/10) write(x/10);
	putchar(x%10+'0');
}
inline void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
	if (!b) { d=a; x=1; y=0; return; } 
	exgcd(b,a%b,d,y,x); y-=x*(a/b);
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (;;)
	{
		read(A); read(B); read(C); read(K); 
		if (!A&&!B&&!C&&!K) break;
		a=C; b=1LL<<K; c=B-A; exgcd(a,b,d,x,y);
		if (c%d) { puts("FOREVER"); continue; }
		b/=d; c/=d; write((((x%b)*c)%b+b)%b); putchar('\n');
	}
	return 0;
}
posted @ 2018-06-01 19:04  空気力学の詩  阅读(125)  评论(0编辑  收藏  举报