HDU - 5514 Frogs

题目大意:有n只青蛙,每只青蛙的弹跳能力为ai,他们都从0出发,绕着m个石头围成的圈子跳跃,石头编号为0~m-1,问能被跳到的石头编号之和

具体思路:首先可以发现弹跳能力为ai的青蛙,可以跳到的石头编号是gcd(ai, m)的倍数

枚举m的因子,若某个青蛙可以弹跳的石头编号中有该因子,那证明编号为这个因子的石头一定会被跳到

num[i]记录编号为i的石头被跳了几次,如果被跳的次数不等于应跳的次数(不为0或1),则减去多余的影响

AC代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,i,j,n,m,vis[100000],num[100000],x,t;
int gcd(int a,int b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}
map <int,int> mp;
vector <int> d;
main()
{
    scanf("%lld",&T);
    for (int tt=1; tt<=T; tt++)
    {
        scanf("%lld%lld",&n,&m);
        int M=(int)sqrt(m);
        for (i=1; i<=M; i++)
        {
            if(m%i==0)
            {
                d.push_back(i);
                if(m/i!=i)d.push_back(m/i);
            }
        }
        sort(d.begin(),d.end());
        memset(vis,0,sizeof vis);
        memset(num,0,sizeof num);
        for(i = 1; i <= n; ++i)
        {
            scanf("%lld",&x);
            t=gcd(x,m);
            M=d.size();
            for(j=0; j<M; ++j)if(d[j]%t==0)vis[j]=1;
        }
        int ans=0;
        M=d.size()-1;
        for(i = 0; i<M; ++i)
            if(vis[i]!=num[i])
            {
                t=(m-1)/d[i];
                ans+=t*(t+1)/2*d[i]*(vis[i]-num[i]);
                t=vis[i]-num[i];
                for(j = i; j <M; ++j)
                    if(d[j]%d[i]==0)num[j]+=t;
            }
        printf("Case #%lld: %lld\n",tt,ans);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Orange-User/p/7767020.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值