zoukankan      html  css  js  c++  java
  • 51nod 1642 区间欧拉函数 && codeforce594D REQ

    画一下柿子就知道是求区间乘积乘区间内所有质因数的(p-1)/p(就是求欧拉的公式嘛)

    看上去莫队就很靠谱然而时间O(nsqrt(n)logn)并不资瓷

    还是离线,确定右端点,对于1~i的区间内的质因数我们在树状数组把他们插入到最后一次出现的位置,然后扫一次求逆元+找质因数O(nlog^2n)

    注意算质因子的时候不能用试除法啊

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    int quick_pow(int A,int p)
    {
        int ret=1;
        while(p!=0)
        {
            if(p%2==1)ret=(LL)ret*A%mod;
            A=(LL)A*A%mod;p/=2;
        }
        return ret;
    }
    int inv(int A){return quick_pow(A,mod-2);}
    
    int pr,prime[1100000],pm[1100000];
    bool v[1100000];
    void get_prime()
    {
        pr=0;
        for(int i=2;i<=1001000;i++)
        {
            if(v[i]==false)prime[++pr]=i,pm[i]=i;
            for(int j=1;j<=pr&&i*prime[j]<=1001000;j++)
            {
                v[i*prime[j]]=true;
                pm[i*prime[j]]=min(pm[i],prime[j]);
                if(i%prime[j]==0)break;
            }
        }
    }
    
    int n;LL s[210000];
    int lowbit(int x){return x&-x;}
    void change(int x,LL k)
    {
        while(x<=n)
        {
            s[x]=s[x]*k%mod;
            x+=lowbit(x);
        }
    }
    LL getsum(int x)
    {
        LL ret=1;
        while(x>0)
        {
            ret=ret*s[x]%mod;
            x-=lowbit(x);
        }
        return ret;
    }
    
    int a[210000];LL sm[210000];
    struct query{int l,r,id;}q[210000];int as[210000];
    bool cmp(query q1,query q2){return q1.r<q2.r;}
    int last[1100000];
    int main()
    {
        get_prime();
        scanf("%d",&n);
        sm[0]=1;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]), sm[i]=sm[i-1]*a[i]%mod;
        int Q;
        scanf("%d",&Q);
        for(int i=1;i<=Q;i++)
            scanf("%d%d",&q[i].l,&q[i].r), q[i].id=i;
        sort(q+1,q+Q+1,cmp);
        
        int j=1;
        memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)s[i]=1;
        for(int i=1;i<=n;i++)
        {
            int d=a[i];
            while(d>1)
            {
                int p=pm[d];LL c=(LL)(p-1)*inv(p)%mod;
                if(last[p]>0)change(last[p],inv(c));
                last[p]=i;
                change(last[p],c);
                while(d%p==0)d/=p;
            }
            
            while(j<=Q&&q[j].r==i)
            {
                as[q[j].id]=sm[q[j].r]*inv(sm[q[j].l-1])%mod*getsum(q[j].r)%mod*inv(getsum(q[j].l-1))%mod;
                j++;
            }
        }
        
        for(int i=1;i<=Q;i++)printf("%d
    ",as[i]);
        return 0;
    }
  • 相关阅读:
    Java Web三层架构设计深思
    编译C源码软件需要的工具
    Hibernate之表间关系
    CSS之颜色字体
    主流的微服务框架
    CSS布局思考
    Android创建新项目及开发
    Google工程师解析Android系统架构
    java多线程实用操作
    Spring IOC/DI/注解
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9887254.html
Copyright © 2011-2022 走看看