蒟蒻求助
查看原帖
蒟蒻求助
201007
Leasier楼主2022/7/17 22:42

RT,看上去像是被卡常了,本地只跑 3.63.6 秒左右。

求助卡常并求问有无时间复杂度更优秀的做法。

代码:

#pragma GCC optimize("Ofast")

#include <iostream>
#include <algorithm>
#include <map>
#include <bitset>
#include <cstring>

using namespace std;

#define set(a, b) a[b >> 5] |= 1 << (b & 31)

typedef long long ll;
typedef unsigned long long ull;

const int N = 42331 + 7, block = 510510, block_size = block >> 5, M = 9, K = 5e8 + 7, P = 7, Q = 1e9 - 1, seed = 1e9 + 7;
int D;
int prime[N], pre_block[block_size + 7], cur_block[block_size + 7], d[M + 7];
char p[block + 7];
map<ull, int> mp[M + 7];
bitset<K> bs;

inline void init(){
	int cnt = 0;
	p[0] = p[1] = true;
	set(pre_block, 0);
	set(pre_block, block);
	for (register int i = 2; i <= block; i++){
		if (!p[i]){
			prime[++cnt] = i;
			if (i > 2) bs[i >> 1] = true;
			if (cnt <= P) set(pre_block, i);
		}
		for (register int j = 1; j <= cnt && i * prime[j] <= block; j++){
			int t = i * prime[j];
			p[t] = true;
			if (j <= P) set(pre_block, t);
			if (i % prime[j] == 0) break;
		}
	}
	for (register int i = 1; i * block <= Q; i++){
		int end = (i + 1) * block - 1, start = i * block;
		memcpy(cur_block, pre_block, sizeof(cur_block));
		for (register int j = P + 1; prime[j] * prime[j] <= end; j++){
			int t1 = max((start - 1) / prime[j] + 1, prime[j]) * prime[j], t2 = prime[j] << 1;
			for (register int k = (t1 & 1 ? t1 : t1 + prime[j]) - start; k < block; k += t2){
				set(cur_block, k);
			}
		}
		for (register int j = 0; j <= block_size; j++){
			int t1 = ~cur_block[j];
			while (t1){
				int t2 = __builtin_ctz(t1);
				if ((j << 5) + t2 >= block) break;
				int cur = start + (j << 5) + t2;
				if (cur > Q) break;
				bs[cur >> 1] = true;
				t1 -= t1 & ((~t1) + 1);
			}
		}
	}
}

int main(){
	int t;
	cin >> t;
	init();
	for (register int i = 1; i <= t; i++){
		ull hash_val = 0;
		cin >> D;
		for (register int j = 1; j <= D; j++){
			cin >> d[j];
		}
		if (D == 1){
			if (!p[d[1]]){
				cout << 1 << endl;
			} else {
				cout << 0 << endl;
			}
			continue;
		}
		sort(d + 1, d + D + 1);
		for (register int j = 1; j <= D; j++){
			hash_val = hash_val * seed + d[j];
		}
		if (mp[D].count(hash_val)){
			cout << mp[D][hash_val] << endl;
			continue;
		}
		int ans = 0;
		for (register int j = D + 1; j <= M; j++){
			d[j] = 0;
		}
		do {
			ans += (d[1] & 1) && (d[1] ^ 5) && d[D] && bs[(d[1] + 10 * d[2] + 100 * d[3] + 1000 * d[4] + 10000 * d[5] + 100000 * d[6] + 1000000 * d[7] + 10000000 * d[8] + 100000000 * d[9]) >> 1];
		} while (next_permutation(d + 1, d + D + 1));
		mp[D][hash_val] = ans;
		cout << ans << endl;
	}
	return 0;
}
2022/7/17 22:42
加载中...