zoukankan      html  css  js  c++  java
  • UVA12546_LCM Pair Sum

    题目的意思是求 [西伽马(p+q)]其中lcm(p,q)=n。

    又见数论呀。

    其实这个题目很简单,考虑清楚了可以很简单的方法飘过。

    我一开始是这样来考虑的。

    对于每一个单独的质因子,如果为p,它的次数为x,那么在p和q中一定有一个为p^x,另一个为p^y(0<=y<=x),只有这样才能保证lcm为p^x。

    这样我们可以枚举第一个为p^x,第二个数就是等比数列求和了。

    同时我们再枚举第二个为p^x,这样我们就又是等比数列求和了。。。。

    这样我们每次分别计算每一个质因子,同时每一个质因子其实是相对独立的,所以我们最后只要做一次乘法就可以了。不过注意每一个质因子出现的次数哦。

    嗯到了这里我们就可以知道了,不过对于每一个答案还是统计了两遍,所以要把多出来的减出来。

    嗯,大概就是这样的。

    但是A掉后,我好像又秒懂了更更简单的办法。诶,深坑啊。自己考虑考虑就知道啦。。。

    这个是经过预处理之后才勉强A掉的,内牛满面啊。。。。。——————————

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define ll long long
    #define M 1000000007
    using namespace std;
    
    ll t,c,p[36],a[36],cas=0;
    ll ans;
    ll f1[30],f2[30],f3[30];
    
    ll power(ll x,ll y)
    {
        ll tot=1;
        while (y)
        {
            if (y&1) tot=(tot*x)%M;
            y>>=1;
            x=(x*x)%M;
        }
        return tot;
    }
    
    ll mod(ll x)
    {
        if (x<M) return x;
        x-=M;
        if (x<M) return x;
        return x-M;
    }
    
    ll count(ll x)
    {
        ll A=1,B=1,F,G;
        for (ll i=1; i<=c; i++)
        {
            if (x&(1<<(i-1)))
            {
                F=(f1[i]*(a[i]+1))%M;
                G=((f2[i]-1)*(f3[i]))%M;
            }
            else
            {
                F=((f1[i]-1)*(f3[i]))%M;
                G=(f1[i]*(a[i]))%M;
            }
            A=(A*F)%M;
            B=(B*G)%M; //cout<<" a: & b: "<<A<<' '<<B<<endl;
        }
        return mod(A+B);
    }
    
    ll over=power(2,M-2);
    
    int main()
    {
        scanf("%lld",&t);
        while (t--)
        {
            ans=0;
            scanf("%lld",&c);
            for (ll i=1; i<=c; i++) scanf("%lld%lld",&p[i],&a[i]);
            for (ll i=1; i<=c; i++)
            {
                f1[i]=power(p[i],a[i]);
                f2[i]=power(p[i],a[i]+1);
                f3[i]=power(p[i]-1,M-2);
            }
            //ans=count(1<<(c)-1);  cout<<"ans : "<<ans<<endl;
            for (ll i=0; i<(1<<c); i++) ans=mod(ans+count(i));
            ll tep=1;
            for (ll i=1; i<=c; i++) tep=(tep*f1[i])%M;
            ans=mod(ans+2*tep);
            ans=(ans*over)%M;
            if (ans<0) ans+=M;
            printf("Case %lld: %lld
    ",++cas,ans);
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    JQuery Easy UI 1.7官网最新版附1.7API
    JS时间戳转换日期格式,附JS脚本详细用法
    JS原生对象实现异步请求以及JQ的ajax请求四种方式
    WebService跨域配置、Ajax跨域请求、附开发过程源码
    反射DataTable转实体类
    前端分页、及分页原理
    源码剖析之sun.misc.Unsafe
    JAVA并发编程学习笔记之CLH队列锁
    java 中的Unsafe
    AbstractQueuedSynchronizer源码解析之ReentrantLock(二)
  • 原文地址:https://www.cnblogs.com/lochan/p/3439630.html
Copyright © 2011-2022 走看看