zoukankan      html  css  js  c++  java
  • HDU 5514 Frogs(容斥原理)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5514

    【题目大意】

      m个石子围成一圈,标号为0~m-1,现在有n只青蛙,每只每次跳a[i]个石子,
      问能被青蛙跳到的石子一共有几个

    【题解】

      我们发现k*gcd(m,a[i])的位置均可以被跳到,那么我们首先筛出m的约数,
      判断其是否被覆盖到,不考虑重复的情况下,
      每个被覆盖到的约数的贡献为x*((m-1)/x)*((m-1)/x+1)/2,
      但是约数的倍数也为约数的情况被重复计算,因此我们按约数从大到小容斥计算答案。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    int T,n,m,p[20010],mark[20010],x,tot;
    LL dp[20010];
    int main(){
        scanf("%d",&T);
        for(int Cas=1;Cas<=T;Cas++){
            memset(dp,0,sizeof(dp));
            memset(mark,0,sizeof(mark));
            scanf("%d%d",&n,&m); tot=0;
            for(int i=1;i*i<=m;i++){
                if(m%i==0){
                    p[++tot]=i;
                    if(i*i!=m)p[++tot]=m/i;
                }
            }sort(p+1,p+tot+1); 
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                int GCD=__gcd(x,m);
                for(int j=1;j<=tot;j++)if(p[j]%GCD==0)mark[j]=1;
            }LL ans=0;
            for(int i=tot;i;i--)if(mark[i]){
                int t=(m-1)/p[i];
                dp[i]=1LL*t*(t+1)/2*p[i];
                for(int j=i+1;j<=tot;j++)if(mark[j]&&p[j]%p[i]==0)dp[i]-=dp[j];
                ans=ans+dp[i];
            }printf("Case #%d: %lld
    ",Cas,ans);
        }return 0;
    }
  • 相关阅读:
    Java统计程序运行时间(转)
    有符号定点数的表示方法
    移位运算符
    索引
    self与super的区别(转)
    Java经典题型(未完成)
    ObjectiveC 的 self 和 super 详解
    边界计算与不对称边界
    各种排序总结
    运算符的优先级
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5514.html
Copyright © 2011-2022 走看看