首页 > 其他分享 >[ARC133B] Dividing Subsequence

[ARC133B] Dividing Subsequence

时间:2023-12-12 20:24:59浏览次数:23  
标签:Dividing int ARC133B Subsequence 序列 本题 define

Dividing Subsequence

这道题与最长公共子序列类似,可以先去水一水那道题。

题意

本题就是让你从 \(p\) 里面选出一个子序列 \(b_i\) 和 \(q\) 里面选出一个子序列 \(a_i\),我们要使 \(b_i\) 是 \(a_i\) 的倍数。

解法

本题直接用动态规划,是 \(O(n^2)\) 做法,会超时,因此我们用树状数组维护区间最值来进行优化,那么本题与最长上升子序列的解法类似——因为我们求了前面的可以求后面的,但是求了后面的就不能求前面的了,而且还要求最长,因此是一个最长上升子序列问题。注意对于 \(p_i\) 更新 \(q_i\) 时要从大到小。

解释很多在代码上,请看代码:

代码

// Problem: [ARC133B] Dividing Subsequence
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/AT_arc133_b
// Memory Limit: 1 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

#define lowbit(x) x & -x
#define pb push_back
#define all(x) x.begin(), x.end()
#define fst ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

typedef long long ll;

const ll N = 1e6 + 10;

int n;     // n个元素
int a[N];  // p数组的每个元素
int b[N];  // q数组的每个元素
int c[N];  // c[]表示i元素在q数组中的位置

vector<int> v[N];  //存储i元素所有的倍数位置
int d[N];
void update(int x, int v) {
  while (x <= n) {
    d[x] = max(d[x], v);
    x += lowbit(x);
  }
}
int query(int x) {
  int res = 0;
  while (x) {
    res = max(d[x], res);
    x -= lowbit(x);
  }
  return res;
}

int main() {
  fst;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  // 3 1 4 2
  // 2 4 1 3
  for (int i = 1; i <= n; i++) {
    cin >> b[i];
    c[b[i]] = i;
  }
  for (int i = 1; i <= n; i++) {
    for (int j = i; j <= n; j += i) {
      //对于i元素,i的倍数是j
      v[i].pb(c[j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    //目标维护a[i]的所有倍数出现的位置
    //对这个位置进行降序排列
    int t = a[i];
    sort(all(v[t]));
    reverse(all(v[t]));
    //就是求这个的最长上升子序列
    for (auto e : v[t]) {
      //对于e元素来说,求来的比我早的,且数值比我小的最大值
      int tmp = query(e - 1);
      update(e, tmp + 1);
    }
  }
  cout << query(n) << endl;
  return 0;
}

本题就愉快地结束了。

标签:Dividing,int,ARC133B,Subsequence,序列,本题,define
From: https://www.cnblogs.com/gongyuchen/p/17897728.html

相关文章

  • [CF83E] Two Subsequences 题解
    [CF83E]TwoSubsequences题解思路定义\(overlap(a,b)\)为字符串\(a\)的后缀与\(b\)的前缀的最大相等的长度,有\(|f(a,b)|=|a|+|b|-overlap(a,b)\),下文称匹配为相邻两串的\(overlap\)。观察到每次操作之后,一定有一个序列是以\(a_i\)为结尾的。所以根据这个......
  • D2. Xor-Subsequence (hard version)
    D2.Xor-Subsequence(hardversion)Itisthehardversionoftheproblem.Theonlydifferenceisthatinthisversion$a_i\le10^9$.Youaregivenanarrayof$n$integers$a_0,a_1,a_2,\ldotsa_{n-1}$.Bryapwantstofindthelongestbeautifulsub......
  • 【刷题笔记】115. Distinct Subsequences
    题目Giventwostrings s and t,return thenumberofdistinctsubsequencesof s whichequals t.Astring's subsequence isanewstringformedfromtheoriginalstringbydeletingsome(canbenone)ofthecharacterswithoutdisturbingtheremainingch......
  • [USACO22OPEN] Up Down Subsequence P
    [USACO22OPEN]UpDownSubsequenceP注意到这个问题是不弱于直接求LIS的,因此考虑dp。设\(f_i\)表示以\(i\)结尾的最长这个什么串的长度,显然没办法直接转移,那么暴力的想法就是多设一维,这样自然就寄了。我们考虑到这样一件事情:如果我们假装对于所有的\(j\),\(j<f_i\)时......
  • CodeForces 946F Fibonacci String Subsequences
    洛谷传送门CF传送门duel的时候差点不会2400了。套路地,考虑每个\(F(x)\)中与\(s\)相同的子序列的贡献。设这个子序列为\(F(x)_{p_1},F(x)_{p_2},F(x)_{p_3},\ldots,F(x)_{p_n}\)。我们想要它成为一个子序列的子串,那么\(F(x)_{[p_1,p_n]}\)中除了\(p_1\simp_......
  • PAT 甲级【1007 Maximum Subsequence Sum】
    本题是考察动态规划与java的快速输入:max[i]表示第i个结尾的最大的连续子串和。bbegin[i]表示第[begin[i],i]为最大和的开始位置超时代码:importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;publicclassMain{@Suppres......
  • CF568E Longest Increasing Subsequence 题解
    LongestIncreasingSubsequenceLIS问题有两种主流\(O(n\logn)\)解法,最常见的树状数组法,以及不那么常见的二分法。然后考虑本题,发现一个神奇的思路就是求出LIS后倒序复原出数组。进一步思考后发现,因为本题是LIS(LongestIncreasingSubsequence)而非LNDS(LongestNon-Decr......
  • Codeforces Round 685 (Div. 2) B. Non-Substring Subsequence
    对于一个长为\(n\)的\(01\)字符串\(s\)有\(n\)个询问。第\(i\)个询问被\(l_i,r_i\)描述\(1\leql_i<r_i\leqn\)。对于每个询问,你需要确定\(s\)中是否存在一个子序列等同于子串\(s[l_i\cdotsr_i]\)。显然子序列可以和子串仅有一个字符不相同。于是\(s......
  • [CF1580D]Subsequence
    D-Subsequence发现\(f(i,j)\)不好处理,考虑将其转换成另一个函数考虑笛卡尔树,\(\min(a_i,a_{i+1},...,a_j)\)就是在笛卡尔树上,\(i\)和\(j\)的\(lca\)那么就可以将问题转移到笛卡尔树上,设\(dp[x][c]\)表示以\(x\)所处的子树中,选了\(c\)个的最大价值那么显然有:\[dp[x][i+j]=\m......
  • Codeforces Round 750 (Div. 2) B. Luntik and Subsequences
    给一个数组\(a_1,a_2,\cdots,a_n\),定义\(s=\sum_{i=1}^{n}a_i\)。询问有多少个\(a\)的子序列满足\(\suma_{i_k}=s-1\)。显然要选出一个\(1\)不加入子序列,任意一个\(0\)可以加入或不加入子序列。于是\(ans=\binom{cnt1}{1}\cdot2^{cnt0}\)。vi......