zoukankan      html  css  js  c++  java
  • hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥

    Senior PanⅡ

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)



    Problem Description

    Senior Pan had just failed in his math exam, and he can only prepare to make up for it. So he began a daily task with Master Dong, Dong will give a simple math problem to poor Pan everyday.
    But it is still sometimes too hard for Senior Pan, so he has to ask you for help.
    Dong will give Pan three integers L,R,K every time, consider all the positive integers in the interval [L,R], you’re required to calculate the sum of such integers in the interval that their smallest divisor (other than 1) is K.

     
    Input
    The first line contains one integer T, represents the number of Test Cases.
    Then T lines, each contains three integers L,R,K(1≤L≤R≤10^11,2≤K≤10^11)
     
    Output
    For every Test Case, output one integer: the answer mod 10^9+7
     
    Sample Input
    2 1 20 5 2 6 3
     
    Sample Output
    Case #1: 5 Case #2: 3
     
    Source

    占坑;。。。其实是不想写,容斥我用莫比乌斯函数推出来的

    突然发现我sb,为什么写大素数测试啊。。。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<bitset>
    #include<set>
    #include<map>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-8
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=3e3+10,M=1e6+10,inf=1e9+10;
    const LL INF=1e18+10,mod=1e9+7;
    
    
    LL gcd(LL a, LL b)
    {
        return b? gcd(b, a % b) : a;
    }
    
    LL multi(LL a, LL b, LL m)
    {
        LL ans = 0;
        a %= m;
        while(b)
        {
            if(b & 1)
            {
                ans = (ans + a) % m;
                b--;
            }
            b >>= 1;
            a = (a + a) % m;
        }
        return ans;
    }
    
    LL quick_mod(LL a, LL b, LL m)
    {
        LL ans = 1;
        a %= m;
        while(b)
        {
            if(b & 1)
            {
                ans = multi(ans, a, m);
                b--;
            }
            b >>= 1;
            a = multi(a, a, m);
        }
        return ans;
    }
    const int Times = 10;
    bool Miller_Rabin(LL n)
    {
        if(n == 2) return true;
        if(n < 2 || !(n & 1)) return false;
        LL m = n - 1;
        int k = 0;
        while((m & 1) == 0)
        {
            k++;
            m >>= 1;
        }
        for(int i=0; i<Times; i++)
        {
            LL a = rand() % (n - 1) + 1;
            LL x = quick_mod(a, m, n);
            LL y = 0;
            for(int j=0; j<k; j++)
            {
                y = multi(x, x, n);
                if(y == 1 && x != 1 && x != n - 1) return false;
                x = y;
            }
            if(y != 1) return false;
        }
        return true;
    }
    
    int vis[M];
    vector<int>pri;
    void init()
    {
        for(int i=2;i<=350000;i++)
        {
            if(!vis[i])
            pri.push_back(i);
            for(int j=i+i;j<=350000;j+=i)
                vis[j]=1;
        }
    }
    LL out;
    void dfs(LL p,int pos,int step,LL L,LL R,LL K)
    {
        if(p*K>R)return;
        LL d=p*K;
        LL x1=(R/d),x2=(L-1)/d;
        //cout<<p<<" "<<d<<" "<<step<<endl;
        //cout<<p<<" "<<pos<<" "<<step<<endl;
        if(step%2==0)
        {
            out+=((multi(x1,x1+1,mod)*1LL*500000004)%mod)*d;
            out%=mod;
            out-=((multi(x2,x2+1,mod)*1LL*500000004)%mod)*d;
            out=(out%mod+mod)%mod;
        }
        else
        {
            out-=((multi(x1,x1+1,mod)*1LL*500000004)%mod)*d;
            out=(out%mod+mod)%mod;
            out+=((multi(x2,x2+1,mod)*1LL*500000004)%mod)*d;
            out%=mod;
        }
        for(int i=pos;i<pri.size();i++)
        {
            if(pri[i]>=K)return;
            if(p*pri[i]*K>R)return;
            dfs(p*pri[i],i+1,step+1,L,R,K);
        }
    }
    int main()
    {
        init();
        int T,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            out=0;
            LL l,r,k;
            scanf("%lld%lld%lld",&l,&r,&k);
            bool isp=Miller_Rabin(k);
            printf("Case #%d: ",cas++);
            if(!isp){
                printf("0
    ");
                continue;
            }
            if(k>=350000)
            {
                if(l<=k&&r>=k)printf("%lld
    ",k%mod);
                else printf("%lld
    ",0);
            }
            else
            {
                dfs(1,0,0,l,r,k);
                printf("%lld
    ",out);
            }
        }
        return 0;
    }
  • 相关阅读:
    [LeetCode] 952. Largest Component Size by Common Factor 按公因数计算最大部分大小
    [LeetCode] 951. Flip Equivalent Binary Trees 翻转等价二叉树
    [LeetCode] 950. Reveal Cards In Increasing Order 按递增顺序显示卡牌
    上周热点回顾(7.6-7.12)团队
    上周热点回顾(6.29-7.5)团队
    上周热点回顾(6.22-6.28)团队
    调用博客园 open api 的客户端示例代码团队
    【故障公告】阿里云 RDS 实例 CPU 100% 故障引发全站无法正常访问团队
    上周热点回顾(6.15-6.21)团队
    《证券投资顾问胜任能力考试》考试大纲
  • 原文地址:https://www.cnblogs.com/jhz033/p/7412586.html
Copyright © 2011-2022 走看看