zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    VUE报错: Duplicate keys detected: '0'. This may cause an update error.
    VUE中 resource如何引入和GET POST JSONP 如何使用
    VUE中 axios GET和POST 如何使用
    微信小程序封装组件,子父组件通信 详细解析
    CSS3文字超出块元素显示省略号
    微信小程序处理后端返回图片二进制流,渲染页面
    记录平台向用户发送消息功能界面(HTML+CSS)
    原生JavaScript写出日历功能 无引用Jq
    mongoTemplate Aggregation first
    封装返回前端的通用格式
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9099627.html
Copyright © 2011-2022 走看看