uva 1404 - Prime k-tuple(数论)

题目链接:uva 1404 1404 - Prime k-tuple

题目大意:如果k个相邻的素数p1,p2,…,pk,满足pk?p1=s,称这些素数组成一个距离为s的素数k元组,给定区间a,b,求有多少个距离s的k元组。

解题思路:筛选素数法,先预处理出[1, sqrt(inf)]的素数表,然后对给定区间[a,b]根据预处理出的素数表筛选出素数即可。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;
typedef long long ll;
const int sqrt_inf = 46340;
const int maxn = 2 * 1e9;

int np, pri[sqrt_inf];
bool vis[maxn+5];
vector<int> vec;

void prime_table (int n) {
    np = 0;
    memset(vis, 0, sizeof(vis));

    for (int i = 2; i <= n; i++) {
        if (vis[i])
            continue;

        pri[np++] = i;
        for (int j = i * i; j <= n; j += i)
            vis[j] = 1;
    }
}

int solve () {
    int ret = 0;
    int a, b, s, k;
    vec.clear();
    memset(vis, 0, sizeof(vis));

    scanf("%d%d%d%d", &a, &b, &k, &s);

    for (int i = 0; i < np && pri[i] * pri[i] <= b; i++) {
        int u = pri[i], d = (u - a % u) % u;

        if (u == a + d)
            d += u;

        while (d <= b - a) {
            vis[d] = 1;
            d += u;
        }
    }

    for (int i = 0; i <= b-a; i++) {
        if (vis[i] == 0 && a + i > 1)
            vec.push_back(a+i);
    }

    for (int i = 0; i + k - 1 < vec.size(); i++) {
        if (vec[i+k-1] - vec[i] == s)
            ret++;
    }

    return ret;
}

int main () {
    prime_table(sqrt_inf);

    int cas;
    scanf("%d", &cas);

    while (cas--) {
        printf("%d\n", solve());
    }
    return 0;
}

uva 1404 - Prime k-tuple(数论)

时间: 2024-08-07 07:57:49

uva 1404 - Prime k-tuple(数论)的相关文章

UVA 1404 - Prime k-tuple(素树筛选)

UVA 1404 - Prime k-tuple 题目链接 题意:找出a-b之间有多少个素数k元组,并且最后一个元素减第一个元素为s 思路:先筛出sqrt的素数,然后对于每个区间,在用这些素数去筛出区间的素数,然后twopointer搞一下即可 代码: #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <vector> usi

UVA - 1404 Prime k-tuple (素数筛选)

Description {p1,..., pk : p1 < p2 <...< pk} is called a prime k -tuple of distance s if p1, p2,..., pk are consecutive prime numbers and pk - p1 = s . For example, with k = 4 , s = 8 , {11, 13, 17, 19} is a prime 4-tuple of distance 8. Given an i

UVA 10140 - Prime Distance(数论)

10140 - Prime Distance 题目链接 题意:求[l,r]区间内最近和最远的素数对. 思路:素数打表,打到sqrt(Max)即可,然后利用大的表去筛素数,由于[l, r]最多100W,所以可以去遍历一遍,找出答案.注意1的情况,一开始没判断1,结果WA了 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define INF 0x3f

UVA 1341 - Different Digits(数论)

UVA 1341 - Different Digits 题目链接 题意:给定一个正整数n,求一个kn使得kn上用的数字最少,如果相同,则输出值最小的 思路: 首先利用鸽笼原理证明最多需要2个数字去组成 设一个数字k,组成k,kk,kkk,kkkk... %n之后余数必然在0 - (n - 1)之间,所以必然能选出两个余数相等的数字相减为0,这个数字就是由0和k组成的. 因此只要考虑一个数字和两个数字的情况,去bfs,记忆化余数,因为余数重复必然形成周期了 代码: #include <stdio.

UVA 1426 - Discrete Square Roots(数论)

UVA 1426 - Discrete Square Roots 题目链接 题意:给定X, N, R,要求r2≡x (mod n) (1 <= r < n)的所有解,R为一个已知解 思路: r2≡x (mod n)=>r2+k1n=x 已知一个r!,带入两式相减得 r2?r12=kn => (r+r1)(r?r1)=kn 枚举A,B,使得 A * B = n (r + r1)为A倍数 (r - r1)为B倍数 这样就可以推出 Aka?r1=Bkb+r1=r => Aka=Bk

UVA 417 - Word Index(数论)

题意:417 - Word Index 题意:每个字符串按题目中那样去映射成一个数字,输入字符串,输出数字 思路:这题还是比较水的,由于一共只有83000多个数字,所以对应一个个数字去映射就可以了,注意字符串进位的情况处理即可 代码: #include <stdio.h> #include <string.h> #include <map> #include <string> using namespace std; char str[10]; map<

UVA 10995 - Educational Journey(数论)

题意:10995 - Educational Journey 题意:给定A遇到C,M,D的时刻和D遇到C,M的时刻,求C遇到M的时刻 思路:先把时间都处理成秒,然后从A遇到C后,从该点出发,A遇到D和C遇到D,就能求出速度Va和Vc之间的关系,由A遇到M后,从该点出发,A遇到D和M遇到D可以推出Va和Vm的关系,从而推出Vc和Vm的关系,然后由C和M遇到点出发,C遇到D和M遇到D的时间可以算,然后又有速度关系,就可以推出他们相遇时间 代码: #include <stdio.h> #includ

UVA 10831 - Gerg&#39;s Cake(数论)

UVA 10831 - Gerg's Cake 题目链接 题意:说白了就是给定a, p,问有没有存在x^2 % p = a的解 思路:求出勒让德标记,判断如果大于等于0,就是有解,小于0无解 代码: #include <stdio.h> #include <string.h> long long a, p; long long pow_mod(long long x, long long k, long long mod) { long long ans = 1; while (k

UVA 12103 - Leonardo&#39;s Notebook(数论置换群)

UVA 12103 - Leonardo's Notebook 题目链接 题意:给定一个字母置换B,求是否存在A使得A^2=B 思路:任意一个长为 L 的置换的k次幂,会把自己分裂成gcd(L,k) 分, 并且每一份的长度都为 L / gcd(l,k),因此平方对于奇数长度不变,偶数则会分裂成两份长度相同的循环,因此如果B中偶数长度的循环个数不为偶数必然不存在A了 代码: #include <stdio.h> #include <string.h> const int N = 30