QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#91254#6134. Soldier Gamehos_lyricAC ✓649ms8664kbC++147.3kb2023-03-28 02:55:102023-03-28 02:55:12

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-28 02:55:12]
  • 评测
  • 测评结果:AC
  • 用时:649ms
  • 内存:8664kb
  • [2023-03-28 02:55:10]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }


// T: monoid representing information of an interval.
//   T()  should return the identity.
//   T(S s)  should represent a single element of the array.
//   T::pull(const T &l, const T &r)  should pull two intervals.
template <class T> struct SegmentTreePoint {
  int logN, n;
  vector<T> ts;
  SegmentTreePoint() {}
  explicit SegmentTreePoint(int n_) {
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
  }
  template <class S> explicit SegmentTreePoint(const vector<S> &ss) {
    const int n_ = ss.size();
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
    for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
    build();
  }
  T &at(int i) {
    return ts[n + i];
  }
  void build() {
    for (int u = n; --u; ) pull(u);
  }

  inline void pull(int u) {
    ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
  }

  // Changes the value of point a to s.
  template <class S> void change(int a, const S &s) {
    assert(0 <= a); assert(a < n);
    ts[a += n] = T(s);
    for (; a >>= 1; ) pull(a);
  }

  // Applies T::f(args...) to point a.
  template <class F, class... Args>
  void ch(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a < n);
    (ts[a += n].*f)(args...);
    for (; a >>= 1; ) pull(a);
  }

  // Calculates the product for [a, b).
  T get(int a, int b) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return T();
    a += n; b += n;
    T prodL, prodR, t;
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
      if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
    }
    t.pull(prodL, prodR);
    return t;
  }

  // Calculates T::f(args...) of a monoid type for [a, b).
  //   op(-, -)  should calculate the product.
  //   e()  should return the identity.
  template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
  auto
#else
  decltype((std::declval<T>().*F())())
#endif
  get(int a, int b, Op op, E e, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return e();
    a += n; b += n;
    auto prodL = e(), prodR = e();
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
      if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
    }
    return op(prodL, prodR);
  }

  // Find min b s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from left to right.
  //   Returns n + 1 if there is no such b.
  template <class F, class... Args>
  int findRight(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a <= n);
    if ((T().*f)(args...)) return a;
    if (a == n) return n + 1;
    a += n;
    for (; ; a >>= 1) if (a & 1) {
      if ((ts[a].*f)(args...)) {
        for (; a < n; ) {
          if (!(ts[a <<= 1].*f)(args...)) ++a;
        }
        return a - n + 1;
      }
      ++a;
      if (!(a & (a - 1))) return n + 1;
    }
  }

  // Find max a s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from right to left.
  //   Returns -1 if there is no such a.
  template <class F, class... Args>
  int findLeft(int b, F f, Args &&... args) {
    assert(0 <= b); assert(b <= n);
    if ((T().*f)(args...)) return b;
    if (b == 0) return -1;
    b += n;
    for (; ; b >>= 1) if ((b & 1) || b == 2) {
      if ((ts[b - 1].*f)(args...)) {
        for (; b <= n; ) {
          if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
        }
        return b - n - 1;
      }
      --b;
      if (!(b & (b - 1))) return -1;
    }
  }
};

////////////////////////////////////////////////////////////////////////////////

struct Node {
  bool a[2][2];
  Node() : a{} {
    a[0][0] = a[1][1] = true;
  }
  Node(int f) : a{} {
    if (f & 1) a[0][0] = true;
    if (f & 2) a[0][1] = true;
    if (f & 4) a[1][0] = true;
  }
  void pull(const Node &l, const Node &r) {
    for (int u = 0; u < 2; ++u) for (int v = 0; v < 2; ++v) {
      a[u][v] =
          (l.a[u][0] && r.a[0][v]) || 
          (l.a[u][1] && r.a[1][v]);
    }
  }
};


constexpr Int INF = 1001001001001001001LL;

int N;
vector<Int> A;

int main() {
  for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
    scanf("%d", &N);
    A.resize(N);
    for (int i = 0; i < N; ++i) {
      scanf("%lld", &A[i]);
    }
    
    vector<pair<Int, int>> es(2 * N - 1);
    for (int i = 0; i < N; ++i) {
      es[i + i] = make_pair(A[i], i + i);
      if (i + 1 < N) {
        es[i + (i + 1)] = make_pair(A[i] + A[i + 1], i + (i + 1));
      }
    }
    sort(es.begin(), es.end());
// cerr<<"es = "<<es<<endl;
    
    vector<int> fs(N, 0);
    SegmentTreePoint<Node> seg(fs);
    Int ans = INF;
    for (int l = 0, r = 0; l < 2 * N - 1; ++l) {
      for (; r < 2 * N - 1 && !seg.ts[1].a[0][0]; ++r) {
        const int j = es[r].second;
        const int i = j / 2;
        if (j & 1) {
          seg.change(i, fs[i] ^= 2);
          seg.change(i + 1, fs[i + 1] ^= 4);
        } else {
          seg.change(i, fs[i] ^= 1);
        }
      }
#ifdef LOCAL
int brt;
for(brt=l+1;brt<=2*N-1;++brt){
 vector<vector<int>>graph(N);
 for(int h=l;h<brt;++h){
  const int j=es[h].second;
  graph[j/2].push_back(j/2+1+(es[h].second&1));
 }
 vector<int>dp(N+1,0);
 dp[0]=1;
 for(int i=0;i<N;++i)if(dp[i])for(const int ii:graph[i])dp[ii]=1;
 if(dp[N])break;
}
if(brt!=(seg.ts[1].a[0][0]?r:2*N)){
 cerr<<"HELP "<<l<<" "<<r<<"; brt = "<<brt<<endl;
 cerr<<"  fs = "<<fs<<endl;
 assert(false);
}
#endif
      if (seg.ts[1].a[0][0]) {
// cerr<<"OK "<<l<<" "<<r<<endl;
        chmin(ans, es[r - 1].first - es[l].first);
      }
      {
        const int j = es[l].second;
        const int i = j / 2;
        if (j & 1) {
          seg.change(i, fs[i] ^= 2);
          seg.change(i + 1, fs[i + 1] ^= 4);
        } else {
          seg.change(i, fs[i] ^= 1);
        }
      }
    }
    printf("%lld\n", ans);
  }
#ifndef LOCAL
  break;
#endif
  }
  return 0;
}


Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3648kb

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: 0
Accepted
time: 578ms
memory: 8664kb

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
2000000000
100
135
103
181
189
84
63
164
176
0
147
135
152
36
200
131
134
0
136
0
72
171
146
0
183
77
176
89
200
135
38
109
119
126
158
189
70
0
38
999804364
188
161
0
116
116
200
0
101
200
39
0
183
139
0
183
107
139
0
178
85993
126
153
168
163
96
53
96
52
126
47
130
79
0
123
188
173
33
0
83
1...

result:

ok 10010 numbers

Test #3:

score: 0
Accepted
time: 73ms
memory: 8624kb

input:

1
100000
-999999999 999999999 999999998 -999999998 -999999997 999999997 999999996 -999999996 999999995 -999999995 -999999994 999999994 -999999993 999999993 -999999992 999999992 -999999991 999999991 999999990 -999999990 999999989 -999999989 999999988 -999999988 999999987 -999999987 999999986 -9999999...

output:

0

result:

ok 1 number(s): "0"

Test #4:

score: 0
Accepted
time: 649ms
memory: 8624kb

input:

10011
1
1000000000
1
-1000000000
2
1000000000 -1000000000
4
1000000000 1000000000 -1000000000 -1000000000
12
48 54 98 -20 -45 56 -100 78 47 23 -100 -21
19
66 41 52 17 -9 -90 -36 90 -26 66 -86 -83 -39 -83 35 78 100 -68 -62
2
-100 -23
17
89 -26 -100 -38 -14 87 32 -100 16 -31 -35 100 73 -61 -100 43 -48...

output:

0
0
0
2000000000
155
168
0
173
137
167
127
25
91
109
176
0
0
173
115
56
66
67
0
1999775909
121
166
128
77
60
146
152
78
172
110
60
200
89
160
200
130
175
79
97
1999891177
122
154
136
164
123
0
175
77
167
76
40
82
79
159
99
141
165
147
158
1999730298
0
179
31
181
192
193
47
91
164
63
65
138
100
168
1...

result:

ok 10011 numbers

Test #5:

score: 0
Accepted
time: 86ms
memory: 8320kb

input:

1
100000
50000 50000 50001 50001 50002 50002 50003 50003 50004 50004 50005 50005 50006 50006 50007 50007 50008 50008 50009 50009 50010 50010 50011 50011 50012 50012 50013 50013 50014 50014 50015 50015 50016 50016 50017 50017 50018 50018 50019 50019 50020 50020 50021 50021 50022 50022 50023 50023 500...

output:

49999

result:

ok 1 number(s): "49999"