zoukankan      html  css  js  c++  java
  • 多校2019 Contest 2 hdu6602 Longest Subarray

    多校2019 Contest 2 hdu6602 Longest Subarray

    给定一个值域在 ([1, m]) 的长度为 (n) 的正整数序列 (a_i) ,求出最长的子序列满足:$$forall xin[1, m], displaystylesum_{i=l}^r[a_i=x]=0, or displaystylesum_{i=l}^r[a_i=x]ge k$$

    (n, m, kleq10^5)

    数据结构


    考虑对于每个右端点 (i) ,不合法的区间为 ([i) 的上 (k-1) 次出现的位置 (+1) (, i]) 。考虑对于这一段区间打 (+1) 标记,询问合法的区间即为找到最小的为 (0) 的位置,可以用线段树维护。由于只需要考虑不同的数的贡献,因此每次修改需要将上一次修改撤销。

    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5 + 10;
    int n, m, k, a[maxn], pos[maxn], pre[maxn], lst[maxn];
    
    vector <int> vec[maxn];
    
    #define mid ((l + r) >> 1)
    #define lson k << 1, l, mid
    #define rson k << 1 | 1, mid + 1, r
    
    int tag[maxn << 2], val[maxn << 2];
    
    inline void pushtag(int k, int x) {
      tag[k] += x, val[k] += x;
    }
    
    inline void pushdown(int k) {
      int &x = tag[k];
      if (x) {
        pushtag(k << 1, x);
        pushtag(k << 1 | 1, x);
        x = 0;
      }
    }
    
    inline void maintain(int k) {
      val[k] = min(val[k << 1], val[k << 1 | 1]);
    }
    
    void upd(int k, int l, int r, int ql, int qr, int x) {
      if (ql <= l && r <= qr) {
        pushtag(k, x); return;
      }
      pushdown(k);
      if (ql <= mid) upd(lson, ql, qr, x);
      if (qr > mid) upd(rson, ql, qr, x);
      maintain(k);
    }
    
    int query(int k, int l, int r) {
      if (l == r) return l;
      pushdown(k);
      assert(val[k] >= 0);
      if (val[k]) return n + 1;
      return val[k << 1] ? query(rson) : query(lson);
    }
    
    #undef mid
    #undef lson
    #undef rson
    
    inline void add(int x, int v) {
      if (x) upd(1, 1, n, lst[x] + 1, x, v);
    }
    
    void solve() {
      memset(pos, 0, (n + 1) << 2);
      memset(lst, 0, (n + 1) << 2);
      memset(tag, 0, (n + 1) << 4);
      memset(val, 0, (n + 1) << 4);
      for (int i = 1; i <= m; i++) {
        vec[i].clear();
      }
      for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
        vec[a[i]].push_back(i);
        pre[i] = pos[a[i]], pos[a[i]] = i;
      }
      for (int i = 1; i <= m; i++) {
        int sz = vec[i].size();
        for (int j = k - 1; j < sz; j++) {
          lst[vec[i][j]] = vec[i][j - k + 1];
        }
      }
      int ans = 0;
      for (int i = 1; i <= n; i++) {
        add(pre[i], -1), add(i, 1);
        ans = max(ans, i - query(1, 1, n) + 1);
      }
      printf("%d
    ", ans);
    }
    
    int main() {
      while (~scanf("%d %d %d", &n, &m, &k)) {
        solve();
      }
      return 0;
    }
    
  • 相关阅读:
    芯片产品介绍
    稀疏矩阵理论与实践
    EUV极紫外光刻技术
    国内AI与芯片企业列表
    中国软件外包现状对比
    GPU指令集技术分析
    寒武纪智能系统参数
    TVM量化路线图roadmap
    EUV光刻机市场与技术
    轻松部署 .NET 5 应用程序,这个指南一定不要错过
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/11312261.html
Copyright © 2011-2022 走看看