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;
    }
  • 相关阅读:
    Python中*和**的区别
    Python中str、list、numpy分片操作
    Python中bisect的使用方法
    Python中__str__和__repr__的区别
    Python中函数参数类型和参数绑定
    C++中explicit
    C++中const
    自动识别 URL
    .net中activex的替代技术:winform control(一)
    vs2005包加载有误的解决方法
  • 原文地址:https://www.cnblogs.com/jhz033/p/7412586.html
Copyright © 2011-2022 走看看