这两道题还是比较简单的,没有什么难度
不过归在数论这个专题里我还是比较认同的,多少有些关系
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('
');
}
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('
');
}
return 0;
}