zoukankan      html  css  js  c++  java
  • 珂朵莉的约数(牛客练习赛9)

    链接:https://www.nowcoder.com/acm/contest/40/F
    来源:牛客网

    珂朵莉给你一个长为n的序列,有m次查询

    每次查询给两个数l,r

    设s为区间[l,r]内所有数的乘积

    求s的约数个数mod 1000000007

    输入描述:

    第一行两个正整数n,m
    第二行一个长为n的序列
    之后m行每行两个数l和r

    输出描述:

    对于每个询问,输出一个整数表示答案

    示例1

    输入

    复制
    5 5
    64 2 18 9 100
    1 5
    2 4
    2 3
    1 4
    3 4

    输出

    复制
    165
    15
    9
    45
    10

    备注:

    对于100%的数据,有n , m <= 100000 , a[i] <= 1000000


    题解:对于1 - 1e6 范围的数他大于1e3的素数因子最多只有一个,我们可以用莫队来维护他,但对于1 - 1e3的来说最多有168个素数因子,所以用一个前缀和,来解决

    调了一天的莫队,wawawawa 很迷茫,然后将那4个while 顺序转换一下,然后就A了。。。。。。。。(真是搞不清楚为啥会 Wa)

    AC code:
    #include <bits/stdc++.h>
       
    using namespace std;
    typedef long long ll;
    const int N = 1e5 + 10;
    const int MOD = 1e9+7;
      
    int prime[1007],tot;bool vis[1007];
    ll inv[N],ans[N],ant;
    int Be[N],a[N],sum[N*10],pre[N][170]; // sum存 在区间内 > 1000 的素数的个数
    void init()
    {
        tot = 0;
        for(int i = 2;i <= 1000;i++)
        {
            if(vis[i])  continue;
            prime[tot++] = i;
            for(int j = i + i; j <= 1000; j += i )
                vis[j] = 1;
        }
    }
       
    struct Mo{
        int l,r,id;
    }Q[N];
    int cmp(Mo a,Mo b){ return Be[a.l] == Be[b.l] ? a.r < b.r : a.l < b.l;}
       
    void add(int pos)
    {
        if(a[pos] == 1) return;
        ant = ant*inv[1+sum[a[pos]]]%MOD;
        sum[a[pos]]++;
        ant = ant*(1+sum[a[pos]])%MOD;
    }
    void del(int pos)
    {
        if(a[pos] == 1) return;
        ant = ant*inv[1+sum[a[pos]]]%MOD;
        sum[a[pos]]--;
        ant = ant*(1+sum[a[pos]])%MOD;
    }
    int main()
    {
        int n,m;
        init();
        scanf("%d%d",&n,&m);
        inv[0] = inv[1] = 1; for(int i=2;i<=n+1;i++) inv[i]=1ll*(MOD-MOD/i)*inv[MOD%i]%MOD ;  // 逆元筛
        int len = sqrt(n);
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
            Be[i] = i/len;
            for(int j = 0;j < tot;j++)
            {
                pre[i][j] = pre[i-1][j];
                while(a[i] % prime[j] == 0)
                {
                    pre[i][j]++;
                    a[i] /= prime[j];
                }
            }
        }
        for(int i = 1;i <= m;i++)   scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].id = i;
        sort(Q+1,Q+m+1,cmp);
        memset(sum,0,sizeof(sum));
        ant = 1;
        int l = 1,r = 0;
        for(int i = 1;i <= m;i++)
        {
            while(r < Q[i].r)   add(r+1),r++;
            while(r > Q[i].r)   del(r),r--;
            while(l < Q[i].l)   del(l),l++;
            while(l > Q[i].l)   add(l-1),l--;
            ll res = 1;
            for(int j=0;j<tot;j++)
                res=1ll*res*(pre[r][j]-pre[l-1][j]+1)%MOD;
            ans[Q[i].id] = 1ll*ant*res %MOD;
        }
        for(int i = 1;i <= m;i++)
            printf("%lld
    ",ans[i]);
        return 0;
    }



  • 相关阅读:
    【思考题】任意长度有理数乘法运算
    【排序】表插入排序算法(C语言版)
    JAVA中的反射
    JAVA中关于日期的最常见的操作
    Hibernate:基于HQL实现数据查询
    Hibernate与Mybatis对比
    使用idea实现SSM框架整合
    基于maven搭建hibernate运行环境
    MYSQL中的存储过程
    MySQL 索引
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/9453034.html
Copyright © 2011-2022 走看看