zoukankan      html  css  js  c++  java
  • Coprimes Gym

    思路:处理每一位右边第一组互质的数的右边数的位置,O(1)处理查询;

    我们先处理对于一个数右边第一个与它互质的数

    从n->1开始

    对于每一个数 对其进行素因数分解,记录每一个素数被那些数所包含

    同时二进制标记处理其本身与那些数不互质

    最后对i-n取反 找第一个1出现的位置,就是右边与它互质的第一个数的位置

    这样我们处理完了右边第一个和它互质数的位置,

    对于第i个数 右边第一对互质的数的右边数的位置应是 min(ans[i],ans[i+1],....ans[n]);

    如果n->1跑的的 就可以写成min(ans[i],ans[i+1]) ps:处理i时i+1已经处理结束;

    这样就可以O(1)处理答案了

    #include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #include<bitset>
    
    #define inf 0x3f3f3f3f
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define sd(x) scanf("%d",&(x))
    #define sl(x) scanf("%lld",&(x))
    #define slf(x) scanf("%lf",&(x))
    #define scs(s) scanf("%s",s)
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define per(i,a,b) for(int i=a;i>=b;i--)
    #define lowbit(x) x&(-x)
    #define ls now<<1
    #define rs now<<1|1
    #define lson l,mid,ls
    #define rson mid+1,r,rs
    #define All L,R
    using namespace std;
    
    const int maxn=5e4+10;
    
    int is_prime[maxn*10],prime[maxn],ans[maxn],a[maxn],tot=0,has[maxn*10];
    
    bitset<maxn> dp[maxn],mark,ok;
    
    
    void make()
    {
        is_prime[1]=is_prime[0]=true;
        for(int i=2;i<=5e5;i++)
        {
            if(!is_prime[i])
            {
                prime[++tot]=i;
            }
            for(int j=1;j<=tot&&i*prime[j]<=5e5;j++)
            {
                is_prime[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    break;
                }
            }
        }
    }
    
    int main()
    {
        int n,m;
        make();
        for(int i=0;i<tot;i++)
            has[prime[i+1]]=i;
        cin>>n>>m;
        rep(i,1,n) cin>>a[i];
        ans[n+1]=maxn;
        for(int i=n;i>=1;i--)
        {
            mark.reset();
            mark[i]=1;
            ok[i]=1;
            for(int j=1;prime[j]*prime[j]<=a[i];j++)
            {
                if(a[i]%prime[j]==0&&a[i])
                {
                    dp[has[prime[j]]][i]=1;
                    mark|=dp[has[prime[j]]];
                }
                while(a[i]%prime[j]==0&&a[i])
                {
                    a[i]/=prime[j];
                }
            }
            if(a[i]) dp[has[a[i]]][i]=1,mark|=dp[has[a[i]]];
            ans[i]=(mark^ok)._Find_first();
            ans[i]=min(ans[i],ans[i+1]);
        }
        while(m--)
        {
            int l,r;
            cin>>l>>r;
            if(ans[l]<=r) cout<<"S
    ";
            else cout<<"N
    ";
        }
    
    
        return 0;
    }
  • 相关阅读:
    POJ 2342.Anniversary party-树形dp
    Codeforces Round #363 (Div. 2) A、B、C
    Codeforces Beta Round #17 D.Notepad 指数循环节
    hdu 5920 Wool 思路
    hdu 5719 Arrange 贪心
    hdu 5718 Oracle 高精度
    hiho #1332 : 简单计算器 栈+递归
    UESTC 1074 秋实大哥搞算数 栈模拟
    cdoj 1329 卿学姐与魔法 优先队列
    cdoj 1324 卿学姐与公主 线段树裸题
  • 原文地址:https://www.cnblogs.com/minun/p/11387482.html
Copyright © 2011-2022 走看看