C - Coprimes Gym - 101492C

1511 ワード

标题:長さnのシーケンスをあげて、m回質問区間[l,r]をあげて、区間内に一対の互質の数があるかどうかを答えます.
題名:まず素数ふるい、開素数ふるい個bitset、bitsetの各ビットに対応するシーケンスの各ビット.後から前へ循環して、2つのbitsetを維持して、aは空になって、bは毎回循環してすべて後の1位を0から1に変えて、それから現在の数の素数の因子を求めて、それからaは素数の因子のbitsetをあるいは起きて、それからbと異なって、使用しますFind_first()は、プラス1が現在ビットの後の最も近い相互質の数の位置であり、後から最小値minn配列を前方に維持し、minn[l]<=rがSを出力しないとNを出力する.
コード:
#include 
using namespace std;
const int maxn=5e5+5;
bitsetp[50000],b,v;
int prime[maxn],vis[maxn];
int a[maxn],pos[maxn],minn[maxn];
void f_prim(){
    prime[0]=0;
    for(int i=2;i=1;i--){
        x=a[i]; v.reset();
        for(int j=1;prime[j]*prime[j]<=x&&j<=prime[0];j++){
            if(x%prime[j]==0){
                v=v|p[j];
                p[j][i-1]=1;
                while(x%prime[j]==0){
                    x/=prime[j];
                }
            }
        }
        if(x>1){
            v=v|p[vis[x]];
            p[vis[x]][i-1]=1;
        }
        b[i]=1;
        v=v^b;
        pos[i]=v._Find_first()+1;
    }
    minn[n+1]=n+1;
    for(int i=n;i>=1;i--){
        minn[i]=min(minn[i+1],pos[i]);
    }
    while(m--){
        int l,r;
        scanf("%d %d",&l,&r);
        if(r>=minn[l]){
            printf("S
"); }else{ printf("N
"); } } return 0; }