题解
M
牛客题目链接
题目描述
Pang believes that one cannot make an omelet without breaking eggs.
For a subset A A A of { 1 , 2 , … , n } \{1,2,\ldots,n\} { 1 , 2 , … , n } , we calculate the score of A A A as follows:
Initialize the score as {0}0.
For any i ∈ A i \in A i ∈ A , add a i a_i a i to the score.
For any pair of integers ( i , j ) (i, j) ( i , j ) satisfying i ≥ 2 i \ge 2 i ≥ 2 , j ≥ 2 j \ge 2 j ≥ 2 , i ∈ A i \in A i ∈ A , if there exists positive integer k > 1 k \gt 1 k > 1 such that i k = j i^k=j i k = j , subtract b j b_j b j from the score.
Find the maximum possible score over the choice of A A A .
思考
我任意选择一个子集A A A ,只考虑条件2,可以得到的分值为∑ i ∈ A a i \sum_{i\in{A}}{a_i} ∑ i ∈ A a i
如果需要扣除b j b_j b j 的得分,必定存在某个i k = j i^k=j i k = j
那么就可以反过来思考,我枚举所有的i k i^k i k ,k ≥ 1 k \ge 1 k ≥ 1 ,i k ≤ n i^k \le n i k ≤ n ,例如:
{ 2 , 4 , 8 , 16 , 32 , … } \{2,4,8,16,32,\ldots\} { 2 , 4 , 8 , 1 6 , 3 2 , … }
{ 3 , 9 , 27 , 91 , … } \{3,9,27,91,\ldots\} { 3 , 9 , 2 7 , 9 1 , … }
{ 5 , 25 , 125 , 625 , … } \{5,25,125,625,\ldots\} { 5 , 2 5 , 1 2 5 , 6 2 5 , … }
{ 6 , 36 , … } \{6,36,\ldots\} { 6 , 3 6 , … }
… \ldots …
对于以上每个集合,分别考虑里面的数字选与不选,比如第一个2 k 2^k 2 k 的集合,当我没有选择2但选择了4的时候,所有b j ( j ∈ A & j = 4 k ) b_j(j \in A \And j=4^k) b j ( j ∈ A & j = 4 k ) 都需要扣除,那么对于单个集合计算的复杂度就是log i n × 2 log i n \log_{i}{n} \times 2^{\log_{i}{n}} log i n × 2 log i n ,那么总体复杂度的上界就是∑ i n log i n × 2 log i n \sum_i^n{\log_{i}{n} \times 2^{\log_{i}{n}}} ∑ i n log i n × 2 log i n ,用起算器算一下当n = 100000 n=100000 n = 1 0 0 0 0 0 的时候,上界不超过2000000 2000000 2 0 0 0 0 0 0 的
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 #include <bits/stdc++.h> using namespace std ;typedef double db;typedef long long ll;typedef unsigned int ui;typedef vector <int > vi;typedef pair<int , int > pii;typedef pair<ll, ll> pll;#define fi first #define se second #define pw(x) (1ll << (x)) #define bt(x, k) (((x) >> k) & 1) #define sz(x) ((int)(x).size()) #define all(x) (x).begin(),(x).end() #define rep(i, l, r) for(int i=(l);i<(r);++i) #define per(i, l, r) for(int i=(r)-1;i>=(l);--i) #define mst(t, v, n) memset(t, v, sizeof(decltype(*(t))) * (n)) #define sf(x) scanf("%d" , &(x)) #if (not defined(ACM_LOCAL) || defined(ACM_TEST)) #define endl '\n' #endif const int N = 1e5 + 10 ;const int MOD = 998244353 ;const int M = 30 ;int n, m;pii a[N], b[N]; int c[N] = {0 };bool vis[N];ll rst; void dfs (int k, ll w) { if (k > m) { rst = max(rst, w); return ; } dfs(k + 1 , w); w += b[k].first; w -= 1l l * b[k].second * c[k]; for (int i = k; i <= m; i += k) { c[i]++; } dfs(k + 1 , w); for (int i = k; i <= m; i += k) { c[i]--; } } void solve () { while (cin >> n) { memset (vis, false , sizeof (vis)); for (int i = 1 ; i <= n; i++) cin >> a[i].first; for (int i = 1 ; i <= n; i++) cin >> a[i].second; ll ans = a[1 ].first; for (int i = 2 ; i <= n; i++) { if (vis[i]) continue ; m = 0 ; for (ll k = i; k <= n; k *= i) { vis[k] = true ; b[++m] = a[k]; } rst = 0 ; dfs(1 , 0 ); ans += rst; } cout << ans << endl ; } } int main () {#ifdef ACM_LOCAL freopen("./data/std.in" , "r" , stdin ); #endif #if (not defined(ACM_LOCAL) || defined(ACM_TEST)) ios_base::sync_with_stdio(false ); cin .tie(0 ); cout .tie(0 ); #endif #ifdef ACM_LOCAL clock_t start = clock(); #endif int t = 1 ; while (t--) solve(); #ifdef ACM_LOCAL clock_t end = clock(); cerr << "Run Time: " << double (end - start) / CLOCKS_PER_SEC << "s" << endl ; #endif return 0 ; }