题意:对于所有的A[I],同时找到左边和右边离它最近且是它的倍数的数相乘最后加起来求和。
解题思路:n*sqrt(n)的算法,开始以为过不了,wa了两发因为lld I64d对拍一个小时发现一个小时前交的代码没错只是没变I64d,。。具体思路是枚举每个a[i]的因子,找离它最近的那个更新,如果已经没更新就不用更新了。用两个辅助数组记录最近的就行。
解题代码:
1 // File Name: 1002.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月19日 星期二 14时10分33秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 int hs[100005]; 28 int hs1[100006]; 29 int ans[100005][2]; 30 int a[100005]; 31 int main(){ 32 //freopen("input.txt","r",stdin); 33 //freopen("output1","w",stdout); 34 int n ; 35 while(scanf("%d",&n) != EOF,n) 36 { 37 38 memset(hs,0,sizeof(hs)); 39 memset(ans,0,sizeof(ans)); 40 memset(hs1,0,sizeof(hs1)); 41 for(int i = 1;i <= n;i ++) 42 { 43 scanf("%d",&a[i]); 44 int p = sqrt(a[i]+1e-8); 45 for(int j = 1;j <= p ;j++) 46 { 47 if(a[i] % j == 0 ) 48 { 49 if(!ans[hs[j]][1]) 50 ans[hs[j]][1] = a[i]; 51 if(!ans[hs[a[i]/j]][1]) 52 ans[hs[a[i]/j]][1] = a[i]; 53 } 54 } 55 hs[a[i]] = i; 56 } 57 for(int i = n;i >= 1;i --) 58 { 59 int p = sqrt(a[i]+1e-8); 60 for(int j = 1;j <= p ;j ++) 61 { 62 if(a[i]%j == 0 ) 63 { 64 if(!ans[hs1[j]][0]) 65 ans[hs1[j]][0] = a[i]; 66 if(!ans[hs1[a[i]/j]][0]) 67 ans[hs1[a[i]/j]][0] = a[i]; 68 } 69 } 70 hs1[a[i]] = i ; 71 } 72 LL sum = 0 ; 73 for(int i = 1;i <= n;i ++) 74 { 75 for(int j = 0 ;j <= 1;j ++) 76 if(!ans[i][j]) 77 ans[i][j] = a[i]; 78 //printf("%d %d ",ans[i][0],ans[i][1]); 79 sum += 1ll*ans[i][0] * ans[i][1]; 80 } 81 printf("%I64d ",sum); 82 } 83 return 0; 84 }