Problem:
Score : 700 points

Problem Statement

We have N gemstones labeled 1 through N.

You can perform the following operation any number of times (possibly zero).

Select a positive integer x, and smash all the gems labeled with multiples of x.

Then, for each i, if the gem labeled i remains without getting smashed, you will receive a_i yen (the currency of Japan).
However, a_i may be negative, in which case you will be charged money.

By optimally performing the operation, how much yen can you earn?

Constraints

All input values are integers.

1 \leq N \leq 100

|a_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N

Output

Print the maximum amount of money that can be earned.

Sample Input 1

6
1 2 -6 4 5 3

Sample Output 1

12

It is optimal to smash Gem 3 and 6.

Sample Input 2

6
100 -100 -100 -100 100 -100

Sample Output 2

200

Sample Input 3

5
-1 -2 -3 -4 -5

Sample Output 3

0

It is optimal to smash all the gems.

Sample Input 4

2
-1000 100000

Sample Output 4

99000

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <numeric>
#include <fstream>
#include <iomanip>

typedef long double ld;
typedef long long ll;
const ll INF = (ll)1e18 + 1;
const ll MOD = 1e9 + 7;

typedef struct {
  ll to;
  ll cap;
  ll rev;
} S_Edge;

// Split
namespace util {

std::vector< std::string > split(std::string s, char delimiter)
{
  std::vector< std::string > vs;
  std::string sub;
  for (auto c : s) {
    if (c == delimiter) vs.push_back(sub), sub.clear();
    else sub += c;
  }
  vs.push_back(sub);
  return vs;
}

} // namespace util

// Minimum, Maximum
template<class T> T minimum(T head, T tail) { return std::min(head, tail); }
template<class H, class... T> H minimum(H head, T... tail) { return std::min(head, minimum(tail...)); }
template<class T> T maximum(T head, T tail) { return std::max(head, tail); }
template<class H, class... T> H maximum(H head, T... tail) { return std::max(head, maximum(tail...)); }

// Output
template<class T, class S> std::ostream& operator << (std::ostream& os, std::pair<T, S> p)
{
  return os << "(" << p.first << " " << p.second << ")";
}

template<class T> std::ostream& operator << (std::ostream& os, std::vector< T > v)
{
  for (ll i = 0; i < (ll)v.size(); i++){ os << " [" << i << "]" << v[i]; if (i % 10 == 9) os << std::endl; }
  //os << v[0]; for (ll i = 1; i < (ll)v.size(); i++){ os << " " << v[i]; }
  return os;
}

template<class T, class S> std::ostream& operator << (std::ostream& os, std::map< T, S > m)
{
  ll i = 0; for (auto p : m){ os << " [" << i << "]" << p.first << "->" << p.second; i++;}
  return os;
}

void print(){ std::cout << std::endl; }
template<typename H> void print(H head) { std::cout << head << std::endl; }
template<typename H, typename... T> void print(H head, T... tail){ std::cout << head << " ", print(tail...); }

ll const MAX_V = 1000;

//
// 最大流
//
std::vector<bool> used(MAX_V);
std::vector<S_Edge> G[MAX_V];

void add_edge(ll from, ll to, ll cap)
{
  G[from].push_back((S_Edge){to, cap, (ll)G[to].size()});
  G[to].push_back((S_Edge){from, 0, (ll)G[from].size()-1});
}

// flow を返す
ll dfs(ll v, ll target, ll flow)
{
  if (v == target) {
    return flow;
  }
  used[v] = true;
  for (ll i = 0; i < (ll)G[v].size(); i++) {
    S_Edge& edge = G[v][i];
    if (!used[edge.to] && edge.cap > 0) {
      ll d = dfs(edge.to, target, std::min(edge.cap, flow));
      if (d > 0) {
	edge.cap -= d;
	G[edge.to][edge.rev].cap += d;
	return d;
      }
    }
  }

  return 0LL;
}

ll max_flow(ll start, ll end)
{
  ll max_flow_val = 0LL;
  for(;;) {
    std::fill(used.begin(), used.end(), false);
    ll flow = dfs(start, end, INF);
    if (flow == 0) return max_flow_val;
    max_flow_val += flow;
  }
}

// 参考にさせて頂いた URL
// http://baitop.hatenadiary.jp/entry/2018/07/29/172100
// 
// 燃やす埋める問題
// s ----(1)----> i ----(2)----> t
// (1) 割らない時の損失
// (2) 割る時の損失
// を入れて解く.
//
// testcase 1
// 3
// -1 3 4
// => 6   ※ 1つ目を割ると, 全部割ることになるので, 最大流は 1
//           sum で 負の成分を足さなくても, 最大流の計算で負の分が加味される
//
// testcase 2
// 3
// -1000 3 4
// => 0   ※ 1つ目を割らないと, 被害が甚大なので, 最大流は 7
//           どんなに最悪な場合でも, 最大流は割る時の損失の総和(=sum) なので, 最終結果は最悪で 0
//           最終結果が負になることはない
//
// testcase 3
// 3
// 3 4 -1000
// => 7   ※ 3つ目を割らないと, 被害が甚大. 最大流は 0 だし, 0 以外流せない
int main()
{
  ll N;
  std::cin >> N;
  std::vector< ll > va(N+1, 0LL);
  for (ll i = 1; i <= N; i++) {
    std::cin >> va[i];
  }

  ll sum = 0LL;
  ll s = 0;
  ll t = N + 1;
  for (ll i = 1; i <= N; i++) {
    if (va[i] >= 0) {
      sum += va[i];
      add_edge(s, i, + 0LL);
      add_edge(i, t, + va[i]);
    } else {
      add_edge(s, i, - va[i]);
      add_edge(i, t, + 0LL);
    }
  }
  for (ll i = 1; i <= N; i++) {
    for (ll j = i; j + i <= N; j += i) {
      add_edge(i, j+i, INF);
    }
  }

  print(max_flow(s, t));
  print(sum - max_flow(s, t));
  return 0;
}