QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#331105#6134. Soldier GameLainWA 1070ms13712kbC++233.9kb2024-02-18 00:24:012024-02-18 00:24:01

Judging History

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

  • [2024-02-18 00:24:01]
  • 评测
  • 测评结果:WA
  • 用时:1070ms
  • 内存:13712kb
  • [2024-02-18 00:24:01]
  • 提交

answer

#include "bits/stdc++.h"
using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int tt;
  cin >> tt;
  while(tt--) {
    int n;
    cin >> n;
    vector<int64_t> a(n);
    for (auto& x : a) cin >> x;

    struct item {
      int64_t val;
      int i, j;

      bool  operator<(const item& o) const {
        return val < o.val;
      }
    };

    vector<item> items;
    items.reserve(2*n);
    for (int i =0; i < n; i++) {
      items.push_back({a[i], i, i});
      if (i) {
        items.push_back({a[i]+a[i-1], i-1, i});
      }
    }
    sort(items.begin(), items.end());

    // DS
    struct DS {
      int n;
      int good_comp_count = 0;
      set<int> comps;
      vector<bool> good;
      vector<bool> self;
      vector<set<int>> selfpos;

      DS (int n) : n(n), good(n), self(n), selfpos(2) {
        for (int i = 0; i < n; i++)
          comps.insert(i);
        comps.insert(n);
      }

      int find(int u) {
        auto it = comps.upper_bound(u);
        return *(--it);
      }
      
      int next_comp(int c) {
        return *comps.upper_bound(c);
      }

      void insert_edge(int u, int v) {
        if (u == v) {
          insert_self_edge(u);
        } else {
          insert_long_edge(u, v);
        }
      }

      bool check_component(int c) {
        int nxt = next_comp(c);
        int len = nxt - c;
        if (len%2 == 0) {
          // even
          return true;
        }
        // odd
        auto& s = selfpos[c%2];
        auto it = s.lower_bound(c);
        return it != s.end() && (*it < nxt);
      }

      void insert_self_edge(int u) {
        int c = find(u);
        self[u] = 1;
        selfpos[u%2].insert(u);
        if (!good[c]) {
          good[c] = check_component(c);
          good_comp_count += good[c];
        }
      }

      void insert_long_edge(int u, int v) {
        v = find(v), u = find(u);
        good_comp_count -= good[v] + good[u];
        comps.erase(v);
        good[u] = check_component(u);
        good_comp_count += good[u];
      }

      void delete_edge(int u, int v) {
        if (u == v) {
          delete_self_edge(u);
        } else {
          delete_long_edge(u, v);
        }
      }

      void delete_self_edge(int u) {
        int c = find(u);
        self[u] = 0;
        selfpos[u%2].erase(u);
        if (good[c]) {
          good[c] = check_component(c);
          good_comp_count += 1 - good[c];
        }
      }

      void delete_long_edge(int u, int v) {
        v = find(v), u = find(u);
        good_comp_count -= good[u];
        comps.insert(v);
        good[u] = check_component(u);
        good[v] = check_component(v);
        good_comp_count += good[v] + good[u];
      }

      bool is_good() {
        return good_comp_count == (comps.size() - 1);
      }
    };

    DS D(n);
    int r =0;
    int64_t ans = 1e18;
    for (int l = 0; l < items.size(); l++) {
      while(r < items.size() && !D.is_good()) {
        D.insert_edge(items[r].i, items[r].j);
        r++;
      }
      if (D.is_good())
        ans = min(ans, items[r-1].val - items[l].val);
      D.delete_edge(items[l].i, items[l].j);
    }
    cout << ans << '\n';

  }
}
// Get all possible sets, order by power - O(n) differnet values
// Iterate over the left endpoint, find smallest right endpoint
// so that it is possible to cover every single node
// Basically check whether the graph has a perfect matching
// Graph is basically a bunch of line graphs and self edges
// The conditions for the graph to have a perfect matching:
// 1. We can consider every component separately
// 2. If a component has an even number of vertices, it is always ok
// 3. If a component has an odd number of vertices, then there must be a self
//    edge at one of positions 0, 2, 4, ... to split into even parts

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3608kb

input:

3
5
-1 4 2 1 1
4
1 3 2 4
1
7

output:

1
2
0

result:

ok 3 number(s): "1 2 0"

Test #2:

score: -100
Wrong Answer
time: 1070ms
memory: 13712kb

input:

10010
1
1000000000
1
-1000000000
2
1000000000 -1000000000
4
1000000000 1000000000 -1000000000 -1000000000
3
100 -100 100
16
-17 91 -19 66 100 -70 -71 76 -58 99 52 19 25 -67 -63 -32
7
-95 -26 63 -55 -19 77 -100
17
-100 72 -53 -32 8 -100 53 44 -100 -65 -81 -59 100 100 57 -47 1
11
99 10 -100 3 32 2 -26...

output:

0
0
0
3000000000
100
213
129
265
196
176
163
267
286
0
284
161
261
136
274
143
214
0
207
0
80
248
239
0
218
77
254
189
265
185
38
209
259
126
187
276
120
0
60
999804364
188
263
0
198
216
268
0
167
248
39
0
283
239
0
275
206
253
0
194
85993
199
239
300
248
175
150
196
66
210
130
237
111
24
207
251
18...

result:

wrong answer 4th numbers differ - expected: '2000000000', found: '3000000000'