BestCoder Round #39 1002——降低复杂度——Mutiple

Problem Description

WLD likes playing with a sequence a[1..N]. One day he is playing with a sequence of N integers. For every index i, WLD wants to find the smallest index F(i) ( if exists ), that i<F(i)n, and aF(i) mod ai = 0. If there is no such an index F(i), we set F(i) as 0.

Input

There are Multiple Cases.(At MOST 10)

For each case:

The first line contains one integers N(1N10000).

The second line contains N integers a1,a2,...,aN(1ai10000),denoting the sequence WLD plays with. You can assume that all ai is distinct.

Output

For each case:

Print one integer.It denotes the sum of all F(i) for all 1i<n

Sample Input
4

1 3 2 4
Sample Output
6
Hint
F(1)=2 F(2)=0 F(3)=4 F(4)=0
大意:求j > i并且 a[j] % a[i]的j的最小值,求所有情况的和
用分解因数的方法不断地维护,就降成n√n的复杂度(alt+41420(小键盘))
1.n√n复杂度
#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

int a[10005];

int b[10005];

int main()

{

    int n;

    while(~scanf("%d",&n)){

        int sum = 0;

        memset(a,0,sizeof(a));

        memset(b,0,sizeof(b));

        for(int i  = 1; i <= n ; i++){

            scanf("%d",&a[i]);

        }



        for(int i = n ; i >= 1;  i--){

            sum += b[a[i]];

            for(int j = 1; j*j <= a[i]; j++){

               if(a[i] % j == 0){

                   b[j] = b[a[i]/j] = i;

               }

            }

        }

        printf("%d\n",sum);

    }

    return 0;

}
View Code

 2.nlogn复杂度

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

using namespace std;

const int MAX = 10010;

int f[MAX],a[MAX];

vector<int> g[MAX];

void inti()

{

    for(int i = 1; i <= MAX ; i++){

        for(int j = i ; j <= MAX; j += i){

            g[j].push_back(i);

        }

    }

}//g保存j的所有的因数

int main()

{

    inti();

    int n;

    while(~scanf("%d",&n)){

        for(int i = 1; i <= n ; i++)

            scanf("%d",&a[i]);

         memset(f,0,sizeof(f));

         int sum = 0;

         for(int i = n ;  i >= 1;  i--){

             sum += f[a[i]];

             for(int j = 0 ; j < g[a[i]].size();j++)

                 f[g[a[i]][j]] = i;

         } 

    printf("%d\n",sum);

    }

    return 0;

}
View Code

用vector预处理得到所有的因数

你可能感兴趣的:(round)