CF-Codeforces Round #673 (Div. 2)-1417C. k-Amazing Numbers【思维】

题目链接
题意:给定一序列 { a 1 , a 2 , a 3 , . . . , a n } \{a_1,a_2,a_3,...,a_n\} {a1,a2,a3,...,an},问该序列所有长度为 i i i的子序列的最大公共元素是多少( i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n
思路:我们注意到:对于某个数字,我们需要考虑区间至少要多大才可以每个区间都包含到它。因此我们维护对于每种数字,其与下一个同种数字的最大距离,同时考虑元素到头和到尾的距离。如此一来就可以知道对于每种数字最短需要多大的区间。之后只要先 ( a n s [ d i s [ 数 字 种 类 ] ] = m i n ( a n s [ d i s [ 数 字 种 类 ] ] , 数 字 种 类 ) ) (ans[dis[数字种类]]=min(ans[dis[数字种类]],数字种类)) (ans[dis[]]=min(ans[dis[]],)),接着维护答案序列的最小值前缀即可。

#include <bits/stdc++.h>
#define pcc pair<char, char>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<ll>
#define rep(i, x, y) for (int i = x; i < y; i++)
#define per(i, x, y) for (int i = x; i >= y; i--)
#define rep0(i, n) for (int i = 0; i < (n); i++)
#define per0(i, n) for (int i = (n)-1; i >= 0; i--)
#define mp make_pair
#define pb push_back
#define F first
#define S second
#define sz(x) (x).size()
#define all(x) (x).begin(), (x).end()
#define ll long long
#define ull unsigned long long
#define db double
#define ld long double
using namespace std;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}

const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 10;
/***************main****************/
ll T = 1;
ll m, n;
ll a[maxn], prv[maxn], dis[maxn], ans[maxn], last[maxn];
int main() {
  T = read();
  while (T--) {
    cin >> n;
    rep(i, 1, n + 1) a[i] = read();
    rep(i, 0, n + 1) ans[i] = dis[i] = prv[i] = last[i] = 0;
    rep(i, 1, n + 1) ans[i] = inf;
    rep(i, 1, n + 1) {
      dis[a[i]] = max(dis[a[i]], i - prv[a[i]]);
      last[a[i]] = i;
      prv[a[i]] = i;
    }
    rep(i, 1, n + 1) if (last[i]) dis[i] = max(dis[i], n + 1 - last[i]);
    rep(i, 1, n + 1) ans[dis[i]] = min(ans[dis[i]], i * 1ll);
    rep(i, 2, n + 1) ans[i] = min(ans[i], ans[i - 1]);
    rep(i, 1, n + 1) cout << (ans[i] == inf ? -1 : ans[i]) << ' ';
    cout << '\n';
  }
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值