• uva 12546


    题意:

      给你一个数n,已经分解过质因子,其中有m个因子a1,a2...am和他们的个数c1,c2....cm,设pair(p,q)满足gcd(p,q)==n && 1<=P<=q<=n,则一共可以找出很多个pair(p1,q1),pair(p2,q2)...pair(pk,qk) 求f(n) = p1+q1+p2+q2.....+pk+qk.

    想法:

      比赛的时候用的2^15的状压,对于一个状态,1代表pair里的第一个数字是满的,即ai^ci,0代表不是满的,可以取ai^0到ai^ci,那么,对于一种状态1001,SUM可以表示成a1^c1*(1+a2+a2^2+...+a2^c2)*(1+a3+a3^2+...+a3^c2)*a4^c4,对于这些个sum,有可能在多个pair中出现,所以还要乘以一个系数,所以我们要求出,对于这个状态,它的合法的pair有多少种,显然,对于1001这个状态cnt = (c1+1)*1*1*(c4+1).就这样把每个状态算出来求和就是结果了,最后还要加上一个少加的n,因为(n,n)这一对只算了1个。

      赛后发现想麻烦了,其实可以直接(1+a1+a1^2...(c1+1)*a1^c1)*(1+a2+a2^2...(c2+1)*a2^c2)*.....*(1+am+am^2...(cm+1)*am^cm)+n,系数直接乘进去和上面那种方法是等价的,代码量却可以缩减很多!!智商啊~

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long LL;
     6 #define MOD 1000000007
     7 int main(){
     8     int T,c,a,b,cases=0;
     9     scanf("%d",&T);
    10     while(T--){
    11         cases++;
    12         scanf("%d",&c);
    13         LL ans=1,flag=1;
    14         for(int i=0;i<c;i++){
    15             LL tem=1,fac=1;;
    16             scanf("%d%d",&a,&b);
    17             for(int i=0;i<b;i++){
    18                 fac = fac * a%MOD;
    19                 tem = (tem + fac) %MOD;
    20             }
    21             tem = (tem + fac*b%MOD)%MOD;
    22             flag = flag*fac%MOD;
    23             ans = ans * tem %MOD;
    24         }
    25         ans = (ans + flag) % MOD;
    26         printf("Case %d: %lld
    ",cases,ans);
    27     }
    28     return 0;
    29 }
    uva 12546
  • 相关阅读:
    bzoj4137[FJOI2015]火星商店问题
    HNOI2019游记
    bzoj4785:[ZJOI2017]树状数组:二维线段树
    快速傅里叶变换(FFT)
    动规大总结
    复习动规(4)
    复习动规(3)
    复习动规(2)
    复习动规(1)
    2019CSP-S游记(真)
  • 原文地址:https://www.cnblogs.com/SolarWings/p/3446474.html
Copyright © 2020-2023  润新知