https://atcoder.jp/contests/arc133/tasks/arc133_b
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int N = 200005;
typedef pair<int, int> PII;
typedef long long ll;
int n;
int a[N];
int b[N];
int dp[N];
bool cmp (PII a, PII b) {
if (a.first != b.first) return a.first < b.first;
return a.second < b.second;
}
void solve() {
cin >> n;
for (int i = 1; i<= n ; i++) {
cin >> a[i];
}
for (int i = 1; i<= n; i ++) {
int t; cin >> t;
b[t] = i;
}
PII lis[N];
int c = 0;
for (int i = 1; i <= n ; i ++) {
for (int j = a[i]; j <= n; j += a[i] ) {
lis[++c] = {i, -b[j]};
}
}
sort(lis + 1, lis + 1 + c, cmp);
int idx = 0;
for (int i = 1; i<= c; i ++) {
int l = 0, r = idx;
while (l < r) {
int mid = l + r + 1>> 1;
if (dp[mid] > lis[i].second) l = mid;//因为是负数所以要反过来
else r = mid - 1;
}
idx = max (idx, r + 1);
dp[r + 1] = lis[i].second;
}
cout << idx << endl;
}
int main () {
int t;
t =1;
while (t --) solve();
return 0;
}
通过埃氏筛法把所有情况筛选出来,然后求最长上升子序列注意按照(i, -j)排序,因为防止选择第一个关键字相同,第二个关键字不同的情况。这样问题就转化成了lis问题 我想的时候在想如何选出倍数,针对每个数,卡在了这儿。实际我们可以先预处理出来所有情况