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

来源:互联网 发布:域名隐藏端口号 编辑:程序博客网 时间:2024/04/30 21:27

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[n]);        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);        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;}
0 0
原创粉丝点击