Description
Input
Output
Sample Input
5 1 2 3 4 5
Sample Output
23
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int MAXN = 1e5 + 10; const int MAXM = 1e4 + 10; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int nums[MAXN]; //序列中的数 int lb[MAXN], rb[MAXN]; //序列中的数左右离他最近的因子的位置 int latest[MAXM];//某个数字最后出现的位置 int main() { int n; while(scanf( "%d", &n ) == 1) { memset( lb, 0, sizeof lb ); memset( rb, INF, sizeof rb ); //reset for(int i = 1; i <= n; i++) { scanf( "%d", &nums[i] ); }//input for(int i = 0; i < MAXM; i++) latest[i] = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= sqrt( nums[i] ); j++) {//遍历每个因子 if(nums[i] % j == 0) { lb[i] = max( lb[i], latest[j] ); lb[i] = max( lb[i], latest[nums[i] / j] ); } } latest[nums[i]] = i; //更新位置,注意要遍历后更新,因为本身也是自己的因子 }// tackle 1 for(int i = 0; i < MAXM; i++) latest[i] = n + 1; for(int i = n; i >= 1; i--) { for(int j = 1; j <= sqrt( nums[i] ); j++) { if(nums[i] % j == 0) { rb[i] = min( rb[i], latest[j] ); rb[i] = min( rb[i], latest[nums[i] / j] ); } } latest[nums[i]] = i; }// tackle 2 同理 ll ans = 0; for(int i = 1; i <= n; i++) { ans = (ans + (i - lb[i])*(rb[i] - i)) % MOD; //统计序列中每个数被统计的次数,可以理解为范围内左边选一个数的选法*右边选一个数的选法。 } printf( "%lld\n", ans ); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/maxichu/article/details/47611819