• BZOJ5358: [Lydsy1805月赛]口算训练


    题解:判断d是否整除,可以转化为求这段区间内d的因子的指数是否均大于d中的指数。容易想到把每个数字都分解为素因子形式,对每个素数出现的次数求个前缀和即可。然而,这样时间空间都不行。注意到对于一个数x,小于sqrt(x)的素因子最多sqrt(x)个,而每个数包含大于sqrt(x)的素因子最多一个。那么容易想到,对于小于sqrt(x)的素因子预处理指数项前缀和。大于sqrt(n)的数,提前分离出来,只需实现区间查询一个数是否出现即可。这个操作,直接分块预处理一下就好了。复杂度o(n×sqrt(n))(大概一辈子都是签到选手了吧。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <set>
    #define mem(MW) memset(MW,0,sizeof(MW))
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    typedef long long ll;
    const int N = 1e5 + 100;
    const int lim = 320;
    inline int read() {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    using namespace std;
    int n, m, a[N];
    int p[N], notp[N], nxt[N];
    void init() {
        notp[1]=1;
        nxt[1]=1;
        rep(i,2,1e5) {
            if(!notp[i])p[++p[0]]=i,nxt[i]=i;
            rep(j,1,p[0]) {
                if(p[j]*i>1e5)break;
                notp[p[j]*i]=1;
                nxt[p[j]*i]=p[j];
                if(i%p[j]==0)break;
            }
        }
    }
    int b[lim+3][N], v[N], cnt, c[N], sum[N], sumc[N];
    void cal_pr(int x) {
        cnt=0;
        while(x!=1) {
            int t=nxt[x];
            v[++cnt]=t; sum[t]=0;
            while(x%t==0)x/=t,++sum[t];
        }
    }
    int belong[N], l[lim+3], r[lim+3], B, num, S[lim+3][N];
    void build() {
        mem(sumc), mem(b), mem(S);
        B=sqrt(n);
        num=n/B;if(n%B)++num;
        rep(i,1,n)belong[i]=(i-1)/B+1;
        rep(i,1,num)l[i]=(i-1)*B+1,r[i]=i*B;r[num]=n;
        rep(i,1,n) {
            cal_pr(a[i]);
            rep(j,1,cnt) {
                if(v[j]<lim) b[v[j]][i]+=sum[v[j]];
                else S[belong[i]][v[j]]+=sum[v[j]];
            }
            c[i]=v[cnt];sumc[i]=sum[v[cnt]];
        }
        rep(j,1,lim)rep(i,2,n) b[j][i]+=b[j][i-1];
    }
    int fd(int L, int R, int x) {
        int tmp=0;
        if(R-L+1<=B) {
            rep(i,L,R) if(c[i]==x) tmp+=sumc[i];
            return tmp>=sum[x];
        }
        rep(i,L,r[belong[L]]) if(c[i]==x) tmp+=sumc[i];
        rep(i,belong[L]+1,belong[R]-1) tmp+=S[i][x];
        rep(i,l[belong[R]],R) if(c[i]==x) tmp+=sumc[i];
        return tmp>=sum[x];
    }
    int ck(int l, int r, int d) {
        int tmp=-1;
        cal_pr(d);
        rep(i,1,cnt) {
            if(v[i]<lim&&b[v[i]][r]-b[v[i]][l-1]<sum[v[i]]) return 0;
            if(v[i]>=lim) tmp=v[i];
        }
        if(tmp==-1) return 1;
        return fd(l,r,tmp);
    }
    int main() {
        int T;
        init();
        T=read();
        while(T--) {
            n=read(), m=read();
            rep(i,1,n) a[i]=read();
            build();
            rep(i,1,m) {
                int l,r,d;
                l=read(), r=read(), d=read();
                if(ck(l,r,d)) puts("Yes");
                else puts("No");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9099627.html
Copyright © 2020-2023  润新知