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;
    }
  • 相关阅读:
    组策略导入导出secedit
    ipad常见错误
    ipad系统路径
    内核操作注册表例子
    WoW64子系统
    win2003 shutdown命令
    regedit 导入注册表
    windbg for CLR
    WM_POWERBROADCAST
    OpenSSL命令
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5514.html
Copyright © 2011-2022 走看看