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>
using namespace std;

typedef long long ll;

int t, a, b, k, s;
vector<int> save;

int pow_mod(int x, int k, int mod) {
	int ans = 1;
	while (k) {
		if (k&1) ans = (ll)ans * x % mod;
		x = (ll)x * x % mod;
		k >>= 1;
	}
	return ans;
}

bool mlrb(int x) {
	if (x == 1 || x == 0) return false;
	for (int i = 0; i < 15; i++) {
		int a = rand() % (x - 1) + 1;
		if (pow_mod(a, x - 1, x) != 1) return false;
	}
	return true;
}

const int N = 10000005;
const int M = 100005;

int prime[M], pn = 0, vis[N];

void getprime() {
	for (int i = 2; i < M; i++) {
		if (vis[i]) continue;
		prime[pn++] = i;
		for (ll j = (ll)i * i; j < M; j += i)
			vis[j] = 1;
	}
}

int main() {
	getprime();
	int now = 0;
	for (int i = 0; i < M; i++) {
		if (prime[now] == i) {
			now++;
			continue;
		}
		vis[i] = 0;
	}
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d%d%d", &a, &b, &k, &s);
		save.clear();
		for (int i = 0; i < pn; i++) {
			if (prime[i] > b) break;
			int tmp = a / prime[i] * prime[i];
			if (tmp < a) tmp += prime[i];
			if (prime[i] == tmp) tmp += prime[i];
			for (int j = tmp; j <= b; j += prime[i]) {
				vis[j - a] = 1;
			}
		}
		for (int i = a; i <= b; i++) {
			if (vis[i - a]) continue;
			save.push_back(i);
		}
		/*for (int i = a; i <= b; i++) {
			if (mlrb(i))
				save.push_back(i);
		}*/
		int n = save.size();
		if (n == 0) {
			printf("0\n");
			continue;
		}
		int pre = 0;
		int cnt = 0;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			cnt++;
			if (cnt >= k || save[i] - save[pre] >= s) {
				if (cnt == k && save[i] - save[pre] == s) ans++;
				while (cnt >= k || save[i] - save[pre] >= s) {
					pre++;
					cnt--;
				}
			}
		}
		printf("%d\n", ans);
		int now = 0;
		for (int i = a; i <= b; i++) {
			if (i == save[now]) {
				now++;
				continue;
			}
			vis[i - a] = 0;
		}
	}
	return 0;
}
时间: 2024-10-10 12:47:20

UVA 1404 - Prime k-tuple(素树筛选)的相关文章

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 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> #incl

UVA - 11983 Weird Advertisement (线段树求并面积)

Description G Weird Advertisement Renat Mullakhanov (rem), one of the most talented programmers in the world, passed away on March 11, 2011. This is very sad news for all of us. His team went to ACM ICPC World Finals - 2004, placed 4th and won gold m

UVA 11983 Weird Advertisement(线段树求矩形并的面积)

UVA 11983 题目大意是说给你N个矩形,让你求被覆盖k次以上的点的总个数(x,y<1e9) 首先这个题有一个转化,吧每个矩形的x2,y2+1这样就转化为了求N个矩形被覆盖k次以上的区域的面积 由于坐标很大,首先考虑的就是将坐标离散化,然后建立线段树tree[][K],表示x的某个区间被覆盖了K次(大于K次算K次)的实际长度,在计算时把矩形转化为一系列横线段(就是说将一个矩形拆开为两条线段,下面的标记为1,上面的标记为-1(这里的标记很有技巧)),然后将这些线段按照y值的从小到达排序(y值相

[2016-02-19][UVA][524][Prime Ring Problem]

UVA - 524 Prime Ring Problem Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbers  into each circle separately, and the

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

POJ 2104 求序列里第K大 主席树裸体题

给定一个n的序列,有m个询问 每次询问求l-r 里面第k大的数字是什么 只有询问,没有修改 可以用归并树和划分树(我都没学过..囧) 我是专门冲着弄主席树来的 对主席树的建树方式有点了解了,不过这题为什么是在主席树里面这么操作的 还是有点不懂,今天照着模板敲了一遍就打多校了 再研究吧 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using name

NOI 2015 荷马史诗【BZOJ 4198】k叉Huffman树

抱歉因为NOIP集训,好长时间没再写题解了. NOI 2015也就只有这道题一看就能懂了…… 4198: [Noi2015]荷马史诗 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 922  Solved: 473[Submit][Status][Discuss] Description 追逐影子的人,自己就是影子. ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是

CodeForces 61E Enemy is weak 求i&lt;j&lt;k &amp;&amp; a[i]&gt;a[j]&gt;a[k] 的对数 树状数组

题目链接:点击打开链接 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 如果只有2元组那就是求逆序数的做法 三元组的话就用一个树状数组x表示 数字i前面有多少个比自己大的个数 然后每次给这个y数组求和,再把x中>a[i]的个数存入y中即可 #include <algorithm> #include <cctype> #include <cassert> #include <cstdio> #in