QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#604091#7685. Barkley IIlongyinTL 3ms30060kbC++175.3kb2024-10-01 23:01:322024-10-01 23:01:33

Judging History

你现在查看的是最新测评结果

  • [2024-10-01 23:01:33]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:30060kb
  • [2024-10-01 23:01:32]
  • 提交

answer

#include <bits/stdc++.h>
#define maxn 1000007
#define int long long
#define dl long double
#define mod 1000000007
#define inf 0x3f3f3f3f
#pragma GCC optimize(2)
using namespace std;
int n, m;
inline int pls(int a, int b) {int m = a + b; return m < mod ? m : m - mod;}
inline int dec(int a, int b) {int m = a - b; return m < 0 ? m + mod : m;}
inline int mul(int a, int b) {return 1ll * a * b % mod;}
inline int fpow(int a, int b) {
  int ans = 1;
  for(; b; b >>= 1,a = mul(a, a)) if(b & 1) ans = mul(ans, a);
  return ans;
}
inline int inv(int a) {return fpow(a, mod - 2);}
inline int dvi(int a, int b) {return mul(a, inv(b));};
inline int qread() {
  char c = getchar(); int num = 0, f = 1;
  for(; !isdigit(c); c=getchar()) if(c == '-') f = -1;
  for(; isdigit(c); c=getchar()) num = num * 10 + c - '0';
  return num * f;
}

#define ls(u) tr[u].s[0]
#define rs(u) tr[u].s[1]
int read() {
  int res = 0, flg = 1; char c = getchar();
  while(c != '-' && !isdigit(c)) c = getchar();
  if(c == '-') flg = 0, c = getchar();
  while(isdigit(c)) {
    res = (res << 3) + (res << 1) + (c ^ 48);
    c = getchar();
  }
  return flg ? res : -res;
}
const int N = 5e5 + 10;
struct Node{
  int s[2];
  int sum;
}tr[N * 20];
int tot, root[N];
void update(int u) {
  tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
}
void build(int& u, int l, int r) {
  u = ++tot;
  if(l == r) return;
  int mid = (l + r) >> 1;
  build(ls(u), l, mid);
  build(rs(u), mid + 1, r);
}
void add(int u, int& v, int l, int r, int val) {
  int mid = (l + r) >> 1;
  v = ++tot;
  tr[v] = {0};
  if(l == r) {
    tr[v].sum = 1;
    return;
  }
  if(val <= mid) {
    rs(v) = rs(u);
    add(ls(u), ls(v), l, mid, val);
  } else {
    ls(v) = ls(u);
    add(rs(u), rs(v), mid + 1, r, val);
  }
  update(v);
}
int check_sum(int u, int v, int l, int r, int ll, int rr) {
  if(rr < ll) return 0;
  if(ll <= l && rr >= r) return tr[v].sum - tr[u].sum;
  int mid = (l + r) >> 1;
  int res = 0;
  if(ll <= mid) res += check_sum(ls(u), ls(v), l, mid, ll, rr);
  if(rr > mid) res += check_sum(rs(u), rs(v), mid + 1, r, ll, rr);
  return res;
}
int check_w(int u, int v, int l, int r) {
  if(tr[v].sum - tr[u].sum == r - l + 1) return 0;
  if(l == r) return l;
  int res = 0;
  int mid = (l + r) >> 1;
  res = check_w(ls(u), ls(v), l, mid);
  if(res) return res;
  return check_w(rs(u), rs(v), mid + 1, r);
}
int check(int l, int r) {
  //cout << l << ' ' << r << '\n';
  if(l > r) return 0;
  return tr[root[r]].sum - tr[root[l - 1]].sum - check_w(root[l - 1], root[r], 1, 2 * n);
}
int val[N];
vector<int> f, bd[N];
tuple<int, int, int> query[N];
int qcnt;

int ans[N];
int vis[N];

struct BIT {
  int tr[N];
  int n;
  BIT(int n) : n(n) {
    for(int i = 1; i <= n; i++) {
      tr[i] = 0;
    } 
  }
  int lowbit(int x) {
      return x & -x;
  }
  
  void add(int x, int k) {
      for (int i = x; i <= n; i += lowbit(i)) {
          tr[i] += k;
      }
  }
  
  long long sum(int x) {
      long long res = 0;
      for (int i = x; i >= 1; i -= lowbit(i)) {
          res += tr[i];
      }
      return res;
  }
};

void cal() {
  sort(query + 1, query + qcnt + 1);
  BIT bit(n);
  for (int i = 1; i <= n; i++) {
    vis[i] = 0;
    ans[i] = 0;
  }
    for (int i = 1, start = 1; i <= qcnt; i++) {
        int l = get<0>(query[i]);
        int r = get<1>(query[i]);
        int id = get<2>(query[i]);
        for (int j = start; j <= r; j++) {
            if (vis[val[j]])
                bit.add(vis[val[j]], -1);
            bit.add(j, 1);
            vis[val[j]] = j;
        }
        start = r + 1;
        ans[id] = bit.sum(r) - bit.sum(l - 1);
    }
}

void solve() {
  n = read(), m = read();
  qcnt = tot = 0;
  build(root[0], 1, 2 * n);
  for(int i = 1; i <= n; i++) {
    val[i] = read();
    f.emplace_back(val[i]);
    f.emplace_back(i);
  }
  sort(f.begin(), f.end());
  f.erase(unique(f.begin(), f.end()), f.end());
  for(int i = 1; i <= n; i++) {
    add(root[i - 1], root[i], 1, 2 * n, upper_bound(f.begin(), f.end(), val[i]) - f.begin());
    bd[upper_bound(f.begin(), f.end(), val[i]) - f.begin()].push_back(i); 
  }
  
  for(int i = 1; i <= 2 * n; i++) {
    if(!bd[i].size()) continue;
    query[++qcnt] = tuple<int, int, int>(1, bd[i][0] - 1, qcnt);
    for(int j = 1; j < bd[i].size(); j++) {
      query[++qcnt] = tuple<int, int, int>(bd[i][j - 1] + 1, bd[i][j] - 1, qcnt);
    }
    query[++qcnt] = tuple<int, int, int>(bd[i][bd[i].size() - 1] + 1, n, qcnt);
  } 
  
  cal();
  int res = check(1, n);
  for (int i = 1; i <= qcnt; i++) {
    int l = get<0>(query[i]);
    int r = get<1>(query[i]);
    int id = get<2>(query[i]);
    if(l > r) continue;
    int num = ans[id];
    //cout << num << ' ' << l << ' ' << r << "*\n";
    res = max(res, num - check_w(root[l - 1], root[r], 1, 2 * n));
  }
  cout << res << '\n';
  /*int res = check(1, n);
  for(int i = 1; i <= 2 * n; i++) {
    if(!bd[i].size()) continue;
    res = max(res, check(1, bd[i][0] - 1));
    for(int j = 1; j < bd[i].size(); j++) {
      res = max(res, check(bd[i][j - 1] + 1, bd[i][j] - 1));
    }
    res = max(res, check(bd[i][bd[i].size() - 1] + 1, n));
  } 
  cout << res << '\n'; */
}

signed main() {
  int t = qread();
  while(t--) {
    solve();
  }
  return 0;
}

详细

Test #1:

score: 100
Accepted
time: 3ms
memory: 30060kb

input:

2
5 4
1 2 2 3 4
5 10000
5 2 3 4 1

output:

2
3

result:

ok 2 number(s): "2 3"

Test #2:

score: -100
Time Limit Exceeded

input:

50000
10 19
12 6 1 12 11 15 4 1 13 18
10 8
8 7 6 7 6 2 2 3 4 8
10 6
3 2 6 6 5 2 3 4 5 6
10 11
6 3 7 9 2 1 2 10 10 4
10 6
6 1 2 6 1 1 3 4 2 1
10 9
8 5 3 9 1 7 5 5 1 1
10 5
1 4 3 2 5 4 5 3 5 2
10 14
3 8 12 10 4 2 3 13 7 3
10 14
5 5 12 2 8 1 13 9 8 5
10 7
5 5 6 6 1 5 3 7 3 4
10 7
5 1 4 6 1 6 4 3 7 5
10...

output:

6
5
4
4
4
4
3
7
4
4
5
5
2
3
6
6
7
5
7
5
5
5
6
3
6
8
7
2
5
5
5
2
4
4
4
5
5
3
7
3
3
4
6
4
6
5
4
4
3
8
6
6
5
7
5
4
5
4
6
6
6
3
7
3
6
4
3
7
6
6
6
7
4
3
6
4
4
5
4
5
6
6
4
5
5
9
4
5
7
3
6
5
2
2
5
6
6
8
4
3
4
5
5
5
7
7
3
2
6
5
3
4
4
4
5
6
5
5
6
7
7
5
5
7
4
7
3
7
6
6
6
5
4
4
5
4
3
3
6
5
4
6
5
5
5
3
5
6
5
6
...

result: