您的位置:首页 > 其它

sduacm16级寒假训练 素筛 快速幂 GCD

2017-02-02 16:28 302 查看

POJ 2739 Sum of Consecutive Prime Numbers

#include<cstdio>
#include<iostream>
using namespace std;
const int maxnp = 10000;
bool isp[maxnp];
int prime[50000], ans[10000 + 5];
int num = 0;
void xs()
{
for(int i = 2; i <= maxnp; i++)
{
if (!isp[i])
prime[num++] = i;
for(int j = 0; j <= num && i * prime[j] <= maxnp; j++)
{
isp[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}
int main()
{
xs();
ans[2] = 1;
for(int i = 3; i <= 10000; i++)
{
int l = 0, r = 0, sum = 2;
for(int j = 1; j < num; j++)
{
if(prime[j] > i)
break;
sum += prime[j];
while (sum > i)
{
sum -= prime[l];
l++;
}
if (sum == i)
ans[i]++;
}
}
int n;
scanf("%d", &n);
while (n)
{
printf("%d\n", ans
);
scanf("%d", &n);
}
return 0;
}


POJ 2689 Prime Distance(大区间素数筛选)

[吐槽]

坚决要吐槽这道题。。。。md,wa了好多发,找了好长时间的错…..(好吧。。。证明我太弱),弱弱地说一

句,筛选长度(<10^6)的素数,我们知道,n最小的质因子a肯定小于根号n(如果a大于根号n,那么与它

对应的因子b肯定小于根n,如果b是素数,那么与a为最小质因子矛盾,如果b为合数,那么肯定能拆成更小

的素数),所以我们把50000内的素数筛出来,然后用这些数去筛掉区间的合数就可以……………………………..

此外,遇到这种在int数据范围极限的数,不要吝啬了,一定要开longlong,不然我打个for循环都崩了……..

还检查好长时间才检查出来

PS:自己制造数据的时候应该有意识地造几个极限数据(也包括极限小那种)

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxnp = 50000;
bool isp[maxnp + 5];
int prime[50000 + 5], ans[10000 + 5], a[1000000 + 5];
bool f[1000000 + 5];
int num = 0;
void xs()
{
for(int i = 2; i <= maxnp; i++)
{
if (!isp[i])
prime[num++] = i;
for(int j = 0; j <= num && i * prime[j] <= maxnp; j++)
{
isp[i * prime[j]] = true;
if (i % prime[j] == 0)
break;
}
}
}
bool cal(int l, int r)
{
memset(f, 0, sizeof(f));
if (l == 1)
f[0] = true;
for(int j = 0; j < num; j++)
{
int k = prime[j];
int i = max(l / k, 2);
i *= k;
while(i <= r)
{
if (i >= l)
f[i - l] = true;
if (i > r - k)
break;
i += k;
}
}
}
int main()
{
xs();
int n, m;
while(cin>>n>>m)
{
int tot = 0;
cal(n, m);
int i = n;
while(i <= m)
{
if (!f[i - n])
a[tot ++] = i;
if (i == 2147483647)
break;
i++;
}
int pp = 1;
if (tot < 2)
{
printf("There are no adjacent primes.\n");
} else
{
int mi = a[1] - a[0], ma = a[1] - a[0], lma = a[0], lmi = a[0];
for(int i = 2; i < tot; i++)
{
int k = a[i] - a[i - 1];
if (k < mi)
{
mi = k;
lmi = a[i - 1];
}
if(k > ma)
{
ma = k;
lma = a[i - 1];
}
}
// printf("%d\n", tot);
printf("%d,%d are closest, %d,%d are most distant.\n", lmi, lmi + mi, lma, lma + ma);
}
}
return 0;
}


POJ 1995 Raising Modulo Numbers 快速幂

#include<cstdio>
#include<iostream>
using namespace std;
int p;
int quick(int a, int b)
{
a = a % p;
int ans = 1;
while (b)
{
if (b & 1)
ans = (ans * a) % p;
a = (a * a) % p;
b /= 2;
}
return ans;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &p);
c259
scanf("%d", &n);
int ans = 0;
for(int i = 0; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
ans = (ans + quick(a, b))% p;
}
printf("%d\n", ans);
}
return 0;
}


[~~~]

我要吐槽一下快速幂,对于a^b,应该先a %= p一下

POJ -3641Pseudoprime numbers(快速幂)

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll p;
ll quick(ll a, ll b)
{
a = a % p;
ll ans = 1LL;
while (b)
{
if (b & 1)
ans = (ans * a) % p;
a = (a * a) % p;
b /= 2;
}
return ans;
}
bool cal(ll x)
{
for(int i = 2; i <= sqrt(x); i++)
if (x % i == 0)
return false;
return true;
}
int main()
{
ll a;
cin>>p>>a;
while(p && a)
{
if (cal(p) || quick(a, p)!=a)
printf("no\n"); else
printf("yes\n");
cin>>p>>a;
}
return 0;
}


同余

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
LL exgcd(LL a, LL b, LL &x, LL &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
LL ans = exgcd(b, a % b, x, y);
int tmp = x;
x = y;
y = tmp - a / b * y;
return ans;
}
LL cal(LL a, LL b, LL c)
{
LL x, y;
LL gcd = exgcd(a, b, x, y);
if (c % gcd != 0)
return -1;
x *= c / gcd;
b /= gcd;
if (b < 0)
b = -b;
x %= b;
if (x <= 0)
x += b;
return x;
}
int main()
{
LL x, y, m, n, l, ans;
cin>>x>>y>>m>>n>>l;
ans = cal(m - n, l, y - x);
if (ans < 0)
printf("Impossible"); else
cout<<ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj