比赛的时候是对于每个数,记录下来a[i], 并记录该树的下标hash[a[i]]
然后枚举a[i]的倍数,如果a[i]的倍数存在(设为k*a[i]),那么vis[k*a[i]]是不为0的
那么可以这样枚举得到最小的下标,但是比赛的时候不懂算时间复杂度,就随便提交了一下,没想到过了。
后来看了下题解,原来时间复杂度是这样算的
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 /* 18 19 */ 20 const int N = 10000 + 10; 21 int vis[N]; 22 int a[N]; 23 int main() 24 { 25 int n, i, ans,j; 26 while (scanf("%d", &n) != EOF) 27 { 28 memset(vis, 0, sizeof(vis)); 29 for (i = 1; i <= n; ++i) 30 { 31 scanf("%d", &a[i]); 32 vis[a[i]] = i; 33 } 34 ans = 0; 35 for (i = 1; i <= n; ++i) 36 { 37 bool find = false; 38 int index; 39 for (j = 2; j*a[i] <= 10000; ++j) 40 { 41 int v = j * a[i]; 42 //找到最小的下标 43 if (!vis[v]) 44 continue; 45 if (vis[v] < i) 46 continue; 47 if (!find) 48 { 49 index = vis[v]; 50 find = true; 51 } 52 else 53 index = min(index, vis[v]); 54 55 } 56 if (find) 57 ans += index; 58 } 59 printf("%d\n", ans); 60 } 61 return 0; 62 }