首页 > 其他分享 >20240816

20240816

时间:2024-09-23 23:17:08浏览次数:1  
标签:return int void tr mid 20240816 dp

Music Festival

我们设状态为当前的炫酷值为 \(i\),则 \(dp_i\) 表示炫酷值,然后将每个专辑按照最大值排序即可

#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;

struct node {
  vector<int> a;
  int maxi;
}x[N];

int t, n, k[N], tr[N * 4], p[N], cnt, dp[N];

bool cmp(node &_x, node &_y) {
  return _x.maxi < _y.maxi;
}

void build(int i, int l, int r) {
  if (l == r) {
    tr[i] = 0;
    return ;
  }
  int mid = (l + r) >> 1;
  build(i * 2, l, mid);
  build(i * 2 + 1, mid + 1, r);
  tr[i] = 0;
}

int query(int i, int l, int r, int x, int y) {
  if (x > y) {
    return 0;
  }
  if (l > y || r < x) {
    return 0;
  }
  if (l >= x && r <= y) {
    return tr[i];
  }
  int mid = (l + r) >> 1;
  return max(query(i * 2, l, mid, x, y), query(i * 2 + 1, mid + 1, r, x, y));
}

void modify(int i, int l, int r, int p) {
  if (l == r) {
    tr[i] = max(tr[i], dp[p]);
    return ;
  }
  int mid = (l + r) >> 1;
  if (mid >= p) modify(i * 2, l, mid, p);
  else modify(i * 2 + 1, mid + 1, r, p);
  tr[i] = max(tr[i * 2], tr[i * 2 + 1]);
}

void Solve() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> k[i];
    for (int j = 1, tmp; j <= k[i]; j++) {
      cin >> tmp;
      x[i].a.push_back(tmp);
      x[i].maxi = max(x[i].maxi, tmp);
      p[++cnt] = tmp;
    }
  }
  sort(p + 1, p + cnt + 1);
  cnt = unique(p + 1, p + cnt + 1) - p - 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < x[i].a.size(); j++) {
      x[i].a[j] = lower_bound(p + 1, p + cnt + 1, x[i].a[j]) - p;
    }
  }
  sort(x + 1, x + n + 1, cmp);
  for (int i = 1; i <= n; i++) {
    int u = 0, maxx = 0, d = 0;
    for (auto cur : x[i].a) {
      u = max(u, cur);
      if (cur > maxx) {
        maxx = cur;
        d = max(d + 1, query(1, 1, cnt, 1, cur - 1) + 1);
        dp[cur] = max(dp[cur], d);
      }
      else dp[cur] = max(dp[cur], 1);
    }
    modify(1, 1, cnt, u);
  }
  int ans = 0;
  for (int i = 1; i <= cnt; i++) {
    ans = max(ans, dp[i]);
  }
  cout << ans << "\n";
  for (int i = 1; i <= n; i++) {
    x[i].a.clear(), x[i].maxi = 0;
  }
  fill(dp + 1, dp + cnt + 1, 0);
  build(1, 1, cnt);
  cnt = 0;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> t;
  while (t--) {
    Solve();
  }
  return 0;
}

Array Collapse

我们可以用单调队列求出上一个比它小的,然后设 \(dp_{i, 0/1}\) 表示当前选到第几个,选或不选

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 5e5 + 5, mod = 998244353;

int t, n, a[N], dp[N][2], l[N], sum[N];

void Solve() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  stack<int> stk;
  for (int i = 1; i <= n; i++) {
    while (!stk.empty() && a[stk.top()] >= a[i]) {
      stk.pop();
    }
    if (stk.empty()) {
      l[i] = 0;
    }
    else l[i] = stk.top();
    stk.push(i);
  }
  dp[0][1] = 1;
  sum[0] = 1;
  for (int i = 1; i <= n; i++) {
    int p = l[i];
    if (p) {
      dp[i][0] = (dp[p][0] + dp[p][1]) % mod;
    }
    else dp[i][0] = 0;
    dp[i][1] = ((dp[p][0] + sum[i - 1] - ((!p) ? 0 : sum[p - 1])) % mod + mod) % mod;
    sum[i] = sum[i - 1] + dp[i][1];
    sum[i] %= mod;
  }
  cout << (dp[n][0] + dp[n][1]) % mod << "\n";
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> t;
  while (t--) {
    Solve();
  }
  return 0;
 }

Intervals

我们可以维护 \(dp_i\) 表示第 \(i\) 个数字为 \(1\) 的最大价值,那么我们考虑他从哪里转移而来如果 \(j\) 如果 \(j >= l[i]\) 那么可以获得当前的价值,这样搞个线段树即可

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int N = 2e5 + 5;

int n, m, l[N], r[N], a[N], tr[N * 4], lazy[N * 4], sum, dp[N], tot;

vector<pair<int, int> > g[N];

void build(int i, int l, int r) {
  if (l == r) {
    tr[i] = 1e18;
    return ;
  }
  int mid = (l + r) >> 1;
  build(i * 2, l, mid);
  build(i * 2 + 1, mid + 1, r);
  tr[i] = 1e18;
}

void pushdown(int i, int l, int r, int mid) {
  tr[i * 2] += lazy[i];
  lazy[i * 2] += lazy[i];
  tr[i * 2 + 1] += lazy[i];
  lazy[i * 2 + 1] += lazy[i];
  lazy[i] = 0;
}

void change(int i, int l, int r, int p) {
  if (l == r) {
    tr[i] = dp[p];
    return ;
  }
  int mid = (l + r) >> 1;
  if (mid >= p) {
    change(i * 2, l, mid, p);
  }
  else change(i * 2 + 1, mid + 1, r, p);
  tr[i] = min(tr[i * 2], tr[i * 2 + 1]);
}

void modify(int i, int l, int r, int x, int y, int z) {
  if (x > y) {
    return ;
  }
  if (l > y || r < x) {
    return ;
  }
  if (l >= x && r <= y) {
    tr[i] += z;
    lazy[i] += z;
    return ;
  }
  int mid = (l + r) >> 1;
  pushdown(i, l, r, mid);
  modify(i * 2, l, mid, x, y, z);
  modify(i * 2 + 1, mid + 1, r, x, y, z);
  tr[i] = min(tr[i * 2], tr[i * 2 + 1]);
}

int query(int i, int l, int r, int x, int y) {
  if (x > y) {
    return 1e18;
  }
  if (l > y || r < x) {
    return 1e18;
  }
  if (l >= x && r <= y) {
    return tr[i];
  }
  int mid = (l + r) >> 1;
  pushdown(i, l, r, mid);
  return min(query(i * 2, l, mid, x, y), query(i * 2 + 1, mid + 1, r, x, y));
}

signed main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    cin >> l[i] >> r[i] >> a[i];
    sum += a[i];
    g[r[i]].push_back({l[i], a[i]});
  }
  build(1, 1, n);
  for (int i = 1; i <= n + 1; i++) {
    for (auto cur : g[i - 1]) {
      tot += cur.second;
      modify(1, 1, n, 1, cur.first - 1, cur.second);
    }
    dp[i] = min(tot, query(1, 1, n, 1, i - 1));
    change(1, 1, n, i);
  }
  cout << max(0ll, sum - query(1, 1, n, 1, n));
  return 0;
}

标签:return,int,void,tr,mid,20240816,dp
From: https://www.cnblogs.com/libohan/p/18428138

相关文章

  • [20240816]oracle21c环境变量ORACLE_PATH与SQLPATH(linux).txt
    [20240816]oracle21c环境变量ORACLE_PATH与SQLPATH(linux).txt--//我记忆以前测试过这个问题,当时是家里的笔记本,安装oracle12.2cforwindows.OS:windows7,发现无法访问SQLPATH或者--//ORACLE_PATH环境变量定义的路径下login.sql文件.我当时解决办法就是登录手工执行init.sql......