C. Complex Market Analysis
C. Complex Market Analysis
题意:给你长度为\(n\)的数组和一个整数\(e\),问你能找到多少对\((i, k)\)使得 \(a\)\(i\) \(*\) \(a\)\(i + e\) \(*\) \(a\)\(i + 2e\).....\(*\) \(a\)\(i + ke\) 是质数,$ i , k >= 1$, \(1 <= a[i] <=\) \(1e\)\(6\)。
思路:先把\(1\) ~ \(1e\)\(6\) 的质数筛选出来,使用埃式筛法,然后对每一个i求前缀且间隔为\(e\)的\(1\)和后缀且间隔为\(e\)的\(1\)的个数,最后遍历整个数组,如果这个数是质数,就可以计算它前面有多少间隔为e的1,后面有多少间隔为\(e\)的\(1\)计算以下即可。
埃氏筛法:
原理:每一个数都可以写成若干个质数的若干次方相乘,我们从2开始进行筛,如果这个数是质数的倍数,就把它筛掉。时间复杂度为
\(O(nlog\)\(log\)\(n\)\()\)。
代码:
for(int i = 2;i <= 1000000; i ++ )
if(!st[i])
for(int j = i * 2; j <= 1000000; j += i)
st[j] = true;
题目代码:
#include <bits/stdc++.h>
#define debug cout << "!!!!!!!!" << endl;
#define pb push_back
#define fi first
#define se second
#define PII pair<int,int>
#define me(a,x) memset(a, x, sizeof(a))
typedef long long LL;
using namespace std;
const int N = 1000100, M = 2e5 + 10;
int a[M], front[M], back[M];
bool st[N];
int cnt, n, e;
void solve()
{
scanf("%d %d",&n, &e);
for(int i = 1; i <= n; i ++ ) front[i] = back[i] = 0;
for(int i = 1; i <= n; i ++ ) scanf("%d",&a[i]);
for(int i = 1; i <= n; i ++ )
{
if(a[i] == 1)
{
front[i] = 1;
if(i - e >= 1) front[i] += front[i - e];
}
}
for(int i = n; i >= 1; i -- )
{
if(a[i] == 1)
{
back[i] = 1;
if(i + e <= n) back[i] += back[i + e];
}
}
LL ans = 0;
for(int i = 1; i <= n; i ++ )
{
if(!st[a[i]])
{
if(i - e >= 1)
{
if(i + e > n || back[i + e] == 0) ans += front[i - e];
else ans += (front[i - e] + 1) * 1LL *(back[i + e] + 1) - 1;
}else{
if(i + e <= n) ans += back[i + e];
}
}
}
printf("%lld\n", ans);
}
int main()
{
int T = 1;
scanf("%d",&T);
st[1] = true;
for(int i = 2;i <= 1000000; i ++ )
if(!st[i])
for(int j = i * 2; j <= 1000000; j += i)
st[j] = true;
while(T -- )
{
solve();
}
return 0;
}

浙公网安备 33010602011771号