Codeforces Round #799 (Div. 4)

前面的题感觉没啥好写的,咕咕咕

H. Gambling

题意

给定一个长度为\(n\)的数组\(x\),问使得最终钱数最大的\(a, l, r\)

收益的计算方式为,初始有\(1\)的钱,从\(x_l\)\(x_r\),遇到一个\(x_i = a\)钱就乘二,反之除2。这里的除法不取整,就是说会搞出\(\frac{1}{2}\)这种数字。

其中\(1 \le n \le 2 \times {10}^5, 1 \le x_i \le {10}^9\)

思路

转化一下就是最终的钱等于\(2^{\sum_{i = l}^{r} [x_i = a] - \sum_{i = l}^{r} [x_i \ne a]}\)。然后为了方便计算比较指数的大小就可以了。

这个问题可以转化成最大子区间和的问题,然后就是DP了。

具体的转化为:对于某个值\(a\),构造一个权值数组\(w\),如果\(x_i = a\)就令\(w_i = 1\),反之令\(w_i = -1\),那么\(w\)的最大子区间和就是答案。

不加任何优化需要\(O(n^2)\)次转移必TLE,需要加点优化。

观察可得最终答案区间的两端的值一定等于\(a\),因为把两端不等于\(a\)的值去掉收益为正。由此第\(i\)个位置只需要考虑\(a = x_i\)的情况。

现在就只需要\(O(n)\)次转移了。

AC代码
// Problem: H. Gambling
// Contest: Codeforces - Codeforces Round #799 (Div. 4)
// URL: https://codeforces.com/contest/1692/problem/H
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

#define CPPIO std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
#define freep(p) p ? delete p, p = nullptr, void(1) : void(0)

#ifdef BACKLIGHT
#include "debug.h"
#else
#define logd(...) ;
#endif

using i64 = int64_t;
using u64 = uint64_t;

void solve_case(int Case);

int main(int argc, char* argv[]) {
  CPPIO;
  int T = 1;
  std::cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve_case(t);
  }
  return 0;
}

void solve_case(int Case) {
  int n;
  std::cin >> n;

  std::vector<int> x(n);
  for (int i = 0; i < n; ++i)
    std::cin >> x[i];

  std::map<int, std::array<int, 3>> dp;
  int max_gain = 0, a, l, r;
  for (int i = 0; i < n; ++i) {
    int v = x[i];
    if (!dp.count(v)) {
      dp[v] = {1, i, i};
    } else {
      auto [gain, l, r] = dp[v];
      int cost = i - r - 1;
      if (gain >= cost) {
        dp[v] = {gain - cost + 1, l, i};
      } else {
        dp[v] = {1, i, i};
      }
    }

    if (dp[v][0] > max_gain) {
      max_gain = dp[v][0];
      a = v;
      l = dp[v][1];
      r = dp[v][2];
    }
  }

  std::cout << a << " " << l + 1 << " " << r + 1 << "\n";
}

posted @ 2022-06-15 01:13  _Backl1ght  阅读(108)  评论(1编辑  收藏  举报