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(1≤N≤10000).
The second line contains N integers a1,a2,...,aN(1≤ai≤10000),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 1≤i<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; }
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; }
用vector预处理得到所有的因数