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

 

posted @ 2013-08-11 21:15  xxx0624  阅读(184)  评论(0编辑  收藏  举报