HDU4611+数学

 1 /*

 2 找规律

 3 题意:abs(i%A - i%B) 对i从0~N-1求和

 4 从0~N-1一个一个算必TLE,着A,B两者差相同的部分合并起来算

 5 */

 6 #include<stdio.h>

 7 #include<string.h>

 8 #include<stdlib.h>

 9 #include<algorithm>

10 #include<iostream>

11 #include<queue>

12 #include<map>

13 #include<math.h>

14 using namespace std;

15 typedef long long int64;

16 //typedef __int64 int64;

17 const int maxn = 105;

18 const int inf = 0x7fffffff;

19 const double pi=acos(-1.0);

20 const double eps = 1e-8;

21 

22 int64 gcd( int64 a,int64 b ){

23     int64 r;

24     while( b ){

25         r = a%b;

26         a = b;

27         b = r;

28     }

29     return a;

30 }

31 

32 int64 lcm( int64 a,int64 b,int64 Gcd ){

33     return a*b/Gcd;

34 }

35 

36 int64 Abs( int64 a ){

37     if( a<0 ) return -a;

38     else return a;

39 }

40 

41 int64 solve( int64 n,int64 a,int64 b ){

42     int64 Index,tmpLen,res,Indexa,Indexb;

43     res = Index = Indexa = Indexb = 0;

44     while( Index<n ){

45         tmpLen = min( a-Indexa,b-Indexb );

46         if( Index+tmpLen>n ) tmpLen = n-Index;//Index:表示新的开始分割的位置

47         res += tmpLen*Abs( Indexa-Indexb );

48         Indexa += tmpLen, Indexa %= a;

49         Indexb += tmpLen, Indexb %= b;

50         Index += tmpLen;

51     }

52     return res;    

53 }        

54 

55 int main(){

56     int T;

57     scanf("%d",&T);

58     while( T-- ){

59         int64 n,a,b;

60         //scanf("%lld%lld%lld",&n,&a,&b);

61         scanf("%I64d%I64d%I64d",&n,&a,&b);

62         int64 LCM = lcm( a,b,gcd(a,b) );

63         int64 ans = 0;

64         if( LCM>=n ) ans = solve( n,a,b );

65         else ans = (n/LCM)*solve( LCM,a,b )+solve( n%LCM,a,b );

66         //printf("%lld\n",ans);

67         printf("%I64d\n",ans);

68     }

69     return 0;

70 }
View Code

 

你可能感兴趣的:(HDU)