题目
https://cn.vjudge.net/problem/Gym-101492C
题意
给你n个数 每次询问一个区间内是否存在互质的数
思路
记录i位置后面第一个与其互质的数的位置
bitset对应每个素数出现的位置
异或后即这些素数出现的位置 即都不互质
再异或 即可得到互质的位置 bitset_Find_frist 查找第一个可行的位置
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e4+100;
typedef long long ll;
int dp[maxn*10],a[maxn];
int prime[maxn*10],p[maxn*10],isprime[maxn*10];
bitset<maxn>dap[maxn],ok,ret;
int cnt;
int n,m;
void getpri()
{
cnt = 0;
for(int i = 2;i < maxn*10;i++)
{
if(isprime[i] == 0)
{
p[i] = cnt;
prime[cnt++] = i;
}
for(int j = 0;j < cnt&&i*prime[j]<maxn*10;j++)
{
isprime[i*prime[j]] = 1;
if(i%prime[j]==0)
break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
getpri();
cin>>n>>m;
dp[n+1] = n+1;
for(int i = 1;i <= n;i++)
cin>>a[i];
for(int i = n;i >= 1;i--)
{
ok[i] = 1;
ret.reset(); //
int x = a[i];
for(int j = 0;j < cnt&&prime[j]*prime[j] <= x;j++)
{
if(x % prime[j] == 0)
{
dap[p[prime[j]]][i] = 1;
ret|=dap[p[prime[j]]];
while(x%prime[j]==0)
x /= prime[j];
}
}
if(x != 1)
dap[p[x]][i] = 1,ret|=dap[p[x]];
dp[i] = (ret^ok)._Find_first();
dp[i] = min(dp[i],dp[i+1]);
}
while(m--)
{
int l,r;
cin>>l>>r;
if(dp[l] <= r)
cout<<"S"<<endl;
else cout<<"N"<<endl;
}
return 0;
}