hdu5514Frogs 容斥

来源:互联网 发布:苹果电脑设计绘图软件 编辑:程序博客网 时间:2024/05/21 11:08
//n只青蛙,每只青蛙每一步跳的步数为a[i]//从0点开始,在一个坐标为0...m-1的环中跳//青蛙跳的次数没有限制//问所有的青蛙中任意一只青蛙能够达到的所有的//坐标之和#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>using namespace std  ;const int maxn = 1e4+10 ;typedef long long ll ;int a[maxn] ;int vis[maxn] ;int num[maxn] ;int b[maxn];int gcd(int aa , int bb){    if(bb==0)      return aa ;    return gcd(bb , aa%bb) ;}int init(int m){    int len = 0 ;    for(int i = 1;i <= sqrt(m);i++)    if(m%i == 0){       b[len++] = i ;       if(i*i != m)       b[len++] = m/i ;    }    return len ;}int main(){   // freopen("d:\\in.txt" , "r" , stdin) ;    int t ; int cas = 0 ;    scanf("%d" , &t) ;    while(t--)    {        int n ; int m ;        scanf("%d%d" , &n,&m) ;        memset(vis , 0 , sizeof(vis)) ;        memset(num , 0 , sizeof(num)) ;        int len = init(m) ;        sort(b,b+len) ;        for(int i = 1;i <= n;i++){            scanf("%d" , &a[i]) ;            int pp = gcd(a[i]  , m) ;            int pos = lower_bound(b,b+len,pp)-b ;            for(int i = pos;i < len;i++)            if(b[i]%pp == 0){               vis[i] = 1 ;            }        }        ll ans = 0 ;        for(int i = 0;i < len;i++){            ll tmp ;            if((tmp = vis[i]-num[i])!=0){                ans += tmp*b[i]*((m-1)/b[i])*((m-1)/b[i]+1)/2 ;                for(int j = i;j < len;j++)                if(b[j]%b[i] == 0)                num[j] += tmp ;            }        }        printf("Case #%d: %lld\n" , ++cas , ans) ;    }    return  0  ;}

0 0