• hdu4777 树状数组


    题意:给了n个数,然后又m次查询,询问[L,R] 内有多少个数与其他的数不互质。

    解:

       我们首先可以通过处理得出每个数的有效区间,LR 就是 左边L位置上的数 和他不互质, 右边R位置上的数和不互质,

       我们对于询问排序,R小的排前面,枚举每个R,在loc位置就将第loc个点在loc的位置加上一个1在loc的L(左不互质点)减一个1,再将枚举到该位的时候对于有在这个位置上R的点 在loc位置减1

      在loc的L位置加1

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <string.h>
    #include <vector>
    #include <cmath>
    using namespace std;
    const int maxn=200005;
    typedef long long LL;
    bool vis[maxn];
    int yinzi[maxn][10],numofYZ[maxn];
    void sieve()
    {
    
         memset(vis,false,sizeof(vis));
         memset(numofYZ,false,sizeof(numofYZ));
        for(LL i=2; i<=200000; i++)
        {
            if(vis[i])continue;
            yinzi[i][numofYZ[i]++]=i;
             for(LL j=i+i; j<=200000; j+=i)
             {
                vis[j]=true;
                yinzi[j][numofYZ[j]++]=i;
             }
        }
    }
    struct point{
       int L,R,id;
       bool operator <(const point &rhs)const {
         return R<rhs.R||( R == rhs.R && L<rhs.L);
       }
    }wLR[maxn],Q[maxn];
    int Loc[maxn];
    int w[maxn];
    vector<int>G[maxn];
    void init(int n)
    {
        for(int i=0; i<=n+1; i++)
            G[i].clear();
    }
    int n,m;
    int C[maxn];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x,int v)
    {
        if(x<=0)return ;
        while(x<=n)
        {
           C[x]+=v;
           x+=lowbit(x);
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=C[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int ans[maxn];
    int main()
    {
        sieve();
        while(scanf("%d%d",&n,&m)==2&&n)
        {
            int maW=0;
            for(int i=1; i<=n; i++)
                {
                    scanf("%d",&w[i]);
                   maW=max(maW,w[i]);
                }
            memset(Loc,0,sizeof(Loc));
            for(int i=1; i<=n; i++)
            {
                int ww=w[i];
                int L=0;
                for(int j=0; j<numofYZ[ ww ]; j++)
                    L=max(L,Loc[ yinzi[ ww ][ j ] ]);
                wLR[i].L=L;
                for(int j=0; j<numofYZ[ ww ]; j++)
                    Loc[ yinzi[ ww ][ j ] ] = i;
            }
            for(int i=0; i<=maW; i++)Loc[i]=n+1;
            for(int i=n; i>0; i--)
            {
                int ww=w[i];
                int R=n+1;
                for(int j=0; j<numofYZ[ ww ]; j++)
                    R=min(R,Loc[ yinzi[ ww ][ j ] ]);
                wLR[i].R=R;
                G[R].push_back(i);
                for(int j=0; j < numofYZ[ ww ]; j++)
                    Loc[ yinzi[ww][ j ] ]=i;
            }
            for(int i=0; i<m; i++)
            {
                    Q[i].id=i;
                    scanf("%d%d",&Q[i].L,&Q[i].R);
            }
            sort(Q,Q+m);
            int now=1;
            memset(C,0,sizeof(C));
            for(int i=0; i<m; i++)
            {
                while(now<=Q[i].R)
                {
                  for(int j=0; j<G[now].size(); j++)
                  {
                      int to=G[now][j];
                      add(to,-1);
                      add(wLR[to].L,1);
                  }
                  add(now,1);
                  add(wLR[now].L,-1); now++;
                }
                ans[Q[i].id]=sum(Q[i].R)-sum(Q[i].L-1);
            }
            for(int i=0; i<m; i++)
                printf("%d
    ",ans[i]);
            init(n);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java全栈day01-03注释、关键字与标识符
    java全栈day01-02入门案例
    java全栈day01-01
    Python中list常用的10个基本方法----list的灰魔法
    python开发[第二篇]------str的7个必须掌握的方法以及五个常用方法
    Python开发【第二篇】:Python基本数据类型
    爬虫相关
    存储库-MongoDB简单的操作
    解析库-beautifulsoup模块
    拉勾网自动发送简历
  • 原文地址:https://www.cnblogs.com/Opaser/p/4934466.html
Copyright © 2020-2023  润新知