• 求一个区间里的一个x,这个x与这区间里面的所有数都互质


    链接:https://ac.nowcoder.com/acm/contest/301/H
    来源:牛客网

    题描述

    小乐乐上了一节数学课,数学老师讲的很好,小乐乐听的也如痴如醉。
    小乐乐听了老师的讲解,知道了什么是素数,现在他想做几个习题。
    现在题目来了:
    首先我们先定义孤独的数:在一个区间中的一个数字x,如果他与这个区间中的任何数都互质,那么他就是孤独的数。
    我们给定一个序列,然后接下来会有多次询问,对于每次询问,给定两个整数l, r,我想知道对于(a[l], a[l + 1], ...., a[r])区间来说中有多少孤独的数。
     
    分析:戴普 ,现在先当模板
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    const int MaxN = 1e5;
    using namespace std;
     
    int n, m, tot;
    int a[MaxN + 5], pri[MaxN + 5];
    int pre[MaxN + 5], last[MaxN + 5], c[MaxN + 5];
    vector <int> V[MaxN + 5], g[MaxN + 5];
    int res[MaxN + 5];
    bool vis[MaxN + 5];
     
    struct NODE {
        int l, r, id;
        bool operator < (const NODE A) const {
            return l < A.l;
        }
    }query[MaxN + 5], seg[MaxN + 5];
     
    bool cmp(NODE A, NODE B)
    {
        return A.r < B.r;
    }
     
    void Init()
    {
        for (int i = 2; i <= MaxN; i++) {
            if(!vis[i]) pri[++tot] = i;
            for (int j = 1; j <= tot && i * pri[j] <= MaxN; j++) {
                vis[i * pri[j]] = 1;
                if(i % pri[j] == 0) break;
            }
        }
        for (int i = 1; i <= tot; i++) {
            for (int j = pri[i]; j <= MaxN; j += pri[i]) V[j].push_back(pri[i]);
        }
    }
     
    void Add(int x, int w)
    {
        if(x == 0) return;
        for (int i = x; i <= MaxN; i += (i & (-i))) c[i] += w;
    }
     
    int Sigma(int x)
    {
        int res = 0;
        for (int i = x; i > 0; i -= (i & (-i))) res += c[i];
        return res;
    }
     
     
    int main()
    {
        Init();
        while(~scanf("%d%d", &n, &m)) {
            memset(c, 0, sizeof(c)); memset(pre, 0, sizeof(pre));
            g[n + 1].clear();
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]), g[i].clear();
            for (int i = 1; i <= n; i++) {
                if(a[i] == 1) {
                    seg[i].l = 0;
                }
                else {
                    int Max = 0;
                    for (int v : V[a[i]]) Max = max(Max, pre[v]);
                    seg[i].l = Max;
                    for (int v : V[a[i]]) pre[v] = i;
                }
            }
            for (int i = 0; i <= MaxN; i++) last[i] = n + 1;
            for (int i = n; i >= 1; i--) {
                if(a[i] == 1) seg[i].r = n + 1;
                else {
                    int Min = n + 1;
                    for (int v : V[a[i]]) Min = min(Min, last[v]);
                    seg[i].r = Min;
                    for (int v : V[a[i]]) last[v] = i;
                }
            }
            for (int i = 1; i <= n; i++) g[seg[i].r].push_back(i);
            for (int i = 1; i <= m; i++) scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i;
            sort (query + 1, query + m + 1, cmp);
            int l = 0;
            for (int i = 1; i <= m; i++) {
                while(l + 1 <= n && l + 1 <= query[i].r) {
                    Add(seg[l + 1].l, 1);
                    for (int v : g[l + 1]) {
                        Add(seg[v].l, -1); Add(v, 1);
                    }
                    l++;
                }
                res[query[i].id] = query[i].r - query[i].l + 1 - Sigma(query[i].r) + Sigma(query[i].l - 1);
            }
            for (int i = 1; i <= m; i++) printf("%d
    ", res[i]);
        }
        return 0;
    }
    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <limits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <map>
    #define lowbit(x) ( x&(-x) )
    #define pi 3.141592653589793
    #define e 2.718281828459045
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    const int N = 1e5+7;
    int w[N],l[N],r[N];//l[i],r[i]保存第i个数的质因子出现的最左位置以及最右位置
    vector<int>V[N];//V[i]存储的是j,其中r[j]=i
    vector<int>have[N],VPrime;//have[i]存储的是数字i分解的质因子,VPrime存储的是[1,200000]的素数
    int ans[N];//存储结果
    int flag[N];
    struct node
    {
        int left,right,id;
    }p[N];
    int cmp(node aa,node bb)
    {
        return aa.right<bb.right;
    }
    int ar[N];
    int lowb(int t)
    {
        return t&(-t);
    }
    void add(int i,int v)
    {
        if(i==0) return;
        for(;i<N;ar[i]+=v,i+=lowb(i));
    }
    int sum(int i)
    {
        int s=0;
        for(;i>0;s+=ar[i],i-=lowb(i));
        return s;
    }
    void getHave(int index,int v)
    {
        int i=0;
        while(v>1&&i<VPrime.size())
        {
            if(VPrime[i]*VPrime[i]>v)
            {
                have[index].push_back(v);
                break;
            }
            if(i<VPrime.size()&& v%VPrime[i]==0)
            {
                have[index].push_back(VPrime[i]);
            }
            while(i<VPrime.size()&& v%VPrime[i]==0)
            {
                v/=VPrime[i];
            }
            i++;
        }
    }
    bool prime[N];
    void init()
    {
        int i,j;
        memset(prime,0,sizeof(prime));
        prime[1]=prime[0]=1;
        for(i=2;i<=N-2;i++)
            for(j=2;i*j<=N-2;j++)
            {
                prime[i*j]=1;
            }
        VPrime.clear();
        for(i=2;i<=N-2;i++)
        {
            if(prime[i]==0)
                VPrime.push_back(i);
        }
        for(i=0;i<N;i++)
        {
            have[i].clear();
        }
        for(i=2;i<N;i++)
        {
            getHave(i,i);
        }
    }
    void init2(int n)//计算出l数组,r数组以及V[]
    {
        for(int i=0;i<=n;i++)
        {
            V[i].clear();
        }
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        memset(flag,0,sizeof(flag));
        for(int i=1;i<=n;i++)
        {
            int left=0;
            for(int j=0;j<have[w[i]].size();j++)
            {
                left=max(left,flag[have[w[i]][j]]);
            }
            l[i]=left;
            for(int j=0;j<have[w[i]].size();j++)
            {
                flag[have[w[i]][j]]=i;
            }
        }
        for(int i=1;i<N;i++)//这里要初始化为n+1
        {flag[i]=n+1;}
        for(int i=n;i>=1;i--)
        {
            int right=n+1;
            for(int j=0;j<have[w[i]].size();j++)
            {
                right=min(right,flag[have[w[i]][j]]);
            }
            r[i]=right;
            for(int j=0;j<have[w[i]].size();j++)
            {
                flag[have[w[i]][j]]=i;
            }
        }
        for(int i=1;i<=n;i++)
        {
            V[r[i]].push_back(i);
        }
    }
    int main()
    {
        int i,j,k;
        int n,m,t;
        init();
        while(scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
        {
            for(i=1;i<=n;i++)
            {
                scanf("%d",&w[i]);
            }
            init2(n);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&p[i].left,&p[i].right);
                p[i].id=i;
            }
            sort(p+1,p+1+m,cmp);
            memset(ar,0,sizeof(ar));
            i=1;
            for(j=1;j<=m;j++)
            {
                while(i<=p[j].right)
                {
                    add(l[i],1);//将左边notFit的+1
                    for(k=0;k<V[i].size();k++)
                    {
                        add(l[V[i][k]],-1);//将左边跟右边同时notFit的-1,去掉重复
                        add(V[i][k],1);//将右边notFit的+1
                    }
                    i++;
                }
                int notFit=sum(p[j].right)-sum(p[j].left-1);
                ans[p[j].id]=p[j].right-p[j].left+1-notFit;
            }
            for(i=1;i<=m;i++)
            {
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    .net core 灵活读取配置文件
    SUSE12SP3-Mysql5.7安装
    SUSE12Sp3-MongoDB安装
    SUSE12Sp3-Supervisor 守护.net core进程
    SUSE12Sp3-Nginx安装
    SUSE12Sp3-.NET Core 2.2.1 runtime安装
    搭建consul 集群
    SUSE12Sp3安装配置.net core 生产环境(1)-IP,DNS,网关,SSH,GIT
    使用Consul 实现 MagicOnion(GRpc) 服务注册和发现
    使用MagicOnion实现gRPC
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10054614.html
Copyright © 2020-2023  润新知