HDOJ 4611 - Balls Rearrangement/2013多校联合第二场A 分情况处理

      2013年多校联合第二场的A题..开始以为有数学方法...整了好久都整不出..这种题还是果断的打表找规律...

      题目实际上要求的是sigma | x%A - x%B |...把每个数的值打出来..发现是一片一片的相同..所以可以利用这一点.直接把答案算出来..但要注意的是..有可能A,B较小..直接模拟会超时..那么处理分为两种情况..当lcm ( A,B )小于10^6...那么就N取摸直接来找...否则..按照一块一块相同的这样从0推到N...


Program:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<stack>
#include<queue>
#include<algorithm>
#define oo 1000000007
#define ll long long 
#define MAXN 1000005 
using namespace std; 
ll gcd(ll a,ll b)
{
       int t;
       while (b) {t=a,a=b,b=t%b;};
       return a; 
}
ll a[MAXN];
int main()
{ 
       ll N,A,B,lcm,temp,ans;
       int i,T; 
       scanf("%d",&T);
       while (T--)
       {
               scanf("%I64d%I64d%I64d",&N,&A,&B);
               if (A>B) temp=A,A=B,B=temp;
               lcm=A*B/gcd(A,B);
               N--;
               if (lcm<=100000) 
               {  
                      a[0]=0;
                      for (i=1;i<=lcm;i++) a[i]=a[i-1]+abs(i%A-i%B);  
                      ans=a[lcm]*(N/lcm)+a[N%lcm];                      
               }else  
               {
                      ll x,h,t,p,a,b;
                      ans=0;
                      x=0;
                      a=A,b=B;
                      while (x<=N)
                      {
                             h=abs(x%A-x%B); 
                             if (a-x<b-x)
                             {
                                   t=min(a,N+1);
                                   ans+=(t-x)*h;
                                   x=a;
                                   a+=A;
                             }else
                             {
                                   t=min(b,N+1);
                                   ans+=(t-x)*h;
                                   x=b;
                                   b+=B;
                             }                         
                      }
               }
               printf("%I64d\n",ans);
       }
       return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值