题目
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;
}