QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#298238#6794. Sequence to Sequenceucup-team087#WA 130ms5016kbC++147.0kb2024-01-05 21:06:222024-01-05 21:06:23

Judging History

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

  • [2024-01-05 21:06:23]
  • 评测
  • 测评结果:WA
  • 用时:130ms
  • 内存:5016kb
  • [2024-01-05 21:06:22]
  • 提交

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 <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#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; }
#define COLOR(s) ("\x1b[" s "m")


unsigned xrand() {
  static unsigned x = 314159265, y = 358979323, z = 846264338, w = 327950288;
  unsigned t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8;
}


constexpr Int INF = 1001001001001001001LL;

Int slow(const vector<Int> &A, const vector<Int> &B) {
  Int ans = 0;
  auto as = A, bs = B;
  auto isBad = [&](int i) -> bool {
    return (as[i] == 1 && bs[i]);
  };
  auto rel = [&](int i) -> Int {
    return (0 <= i && i < (int)as.size()) ? (as[i] - bs[i]) : 0;
  };
  for (; ; ) {
    const int n = as.size();
    int im = -1;
    for (int i = 0; i < n; ++i) if (!bs[i]) {
      im = i;
      break;
    }
    if (!~im) {
      break;
    }
    int l0 = im, r0 = im + 1;
    for (; l0 > 0 && !isBad(l0 - 1); --l0) {}
    for (; r0 < n && !isBad(r0); ++r0) {}
    int l = -1, r = -1;
    for (int i = l0; i <= im; ++i) if (rel(i - 1) < rel(i)) {
      l = i;
      break;
    }
    for (int i = r0; i >= im + 1; --i) if (rel(i - 1) > rel(i)) {
      r = i;
      break;
    }
    assert(~l);
    assert(~r);
    // sub 1 from [l, r)
    ++ans;
    for (int i = l; i < r; ++i) --as[i];
    vector<Int> aas, bbs;
    for (int i = 0; i < n; ++i) if (as[i]) {
      aas.push_back(as[i]);
      bbs.push_back(bs[i]);
    }
    as.swap(aas);
    bs.swap(bbs);
  }
  {
    const int n = as.size();
    for (int i = 0; i <= n; ++i) if (rel(i - 1) < rel(i)) {
      ans += (rel(i) - rel(i - 1));
    }
  }
  return ans;
}

/*
  slow strategy in order:
    -1 x[l,r] times
    ignore B[i]=0
    +1 y[l,r] times
    -1 z[l,r] times
  
  min. \sum x[l,r] + \sum y[l,r] + \sum z[l,r]
  sub. to
    x, y, z >= 0
    if B[i] > 0:
      A[i] - \sum x[l,r] >= 1
      A[i] - \sum x[l,r] + \sum y[l,r] - \sum z[l,r] = B[i]
    if B[i] = 0:
      A[i] - \sum x[l,r] <= 0
  
  dual
  B[i] > 0: p[i], q[i]
  B[i] = 0: r[i]
  
  max. \sum (1-A[i]) p[i] + \sum (B[i]-A[i]) q[i] + \sum (0-A[i]) r[i]
  sub. to
    p >= 0
    r <= 0
    \sum[i] (-p[i]) + \sum[i] (-q[i]) + \sum[i] (-r[i]) <= 1
    \sum[i] q[i] <= 1
    \sum[i] (-q[i]) <= 1
*/
Int fast(const vector<Int> &A, const vector<Int> &B) {
  const int N = A.size();
  for (int i = 0; i < N; ++i) if (!A[i] && B[i]) {
    return -1;
  }
  // state: max suffix
  Int crt[2][2][2];
  for (int x = 0; x <= 1; ++x) for (int y = 0; y <= 1; ++y) for (int z = 0; z <= 1; ++z) {
    crt[x][y][z] = -INF;
  }
  crt[0][0][0] = 0;
  for (int i = 0; i < N; ++i) {
    Int nxt[2][2][2];
    for (int x = 0; x <= 1; ++x) for (int y = 0; y <= 1; ++y) for (int z = 0; z <= 1; ++z) {
      nxt[x][y][z] = -INF;
    }
    if (B[i]) {
      for (int x = 0; x <= 1; ++x) for (int y = 0; y <= 1; ++y) for (int z = 0; z <= 1; ++z) {
        for (int p = 0; p <= 1; ++p) for (int q = -1; q <= 1; ++q) {
          const int xx = max(x - p - q, 0);
          const int yy = max(y + q, 0);
          const int zz = max(z - q, 0);
          if (xx <= 1 && yy <= 1 && zz <= 1) {
            chmax(nxt[xx][yy][zz], crt[x][y][z] + (1 - A[i]) * p + (B[i] - A[i]) * q);
          }
        }
      }
    } else {
      for (int x = 0; x <= 1; ++x) for (int y = 0; y <= 1; ++y) for (int z = 0; z <= 1; ++z) {
        for (int r = -1; r <= 0; ++r) {
          const int xx = max(x - r, 0);
          if (xx <= 1) {
            chmax(nxt[xx][y][z], crt[x][y][z] + (0 - A[i]) * r);
          }
        }
      }
    }
    memcpy(crt, nxt, sizeof(nxt));
  }
  Int ans = -INF;
  for (int x = 0; x <= 1; ++x) for (int y = 0; y <= 1; ++y) for (int z = 0; z <= 1; ++z) {
    chmax(ans, crt[x][y][z]);
  }
  return ans;
}
/*
  HELP
  [1, 4, 2, 3, 3, 1, 1] [2, 0, 0, 1, 0, 0, 2]: 7 7 6
  [3, 2, 2, 3, 2] [4, 0, 1, 0, 3]: 6 6 5
*/

void stress() {
  constexpr int lim = 4;
  for (int iter = 1; ; ++iter) {
    const int n = 1 + xrand() % 5;
    vector<Int> ini(n);
    for (int i = 0; i < n; ++i) {
      ini[i] = 1 + xrand() % lim;
    }
cerr<<"iter = "<<iter<<", ini = "<<ini<<endl;
    queue<vector<Int>> que;
    map<vector<Int>, int> dist;
    dist[ini] = 0;
    que.push(ini);
    for (; que.size(); ) {
      const auto as = que.front();
      que.pop();
      const int c = dist[as];
      for (const int sig : {+1, -1}) {
        for (int l = 0; l <= n; ++l) for (int r = l + 1; r <= n; ++r) {
          auto bs = as;
          bool ok = true;
          for (int i = l; i < r; ++i) if (as[i]) {
            bs[i] += sig;
            ok = ok && (0 <= bs[i] && bs[i] <= lim + 1);
          }
          if (ok) {
            auto it = dist.find(bs);
            if (it != dist.end() && it->first == bs) {
              //
            } else {
              dist[bs] = c + 1;
              que.push(bs);
            }
          }
        }
      }
    }
    for (const auto &kv : dist) {
      const auto tar = kv.first;
      bool ok = true;
      for (int i = 0; i < n; ++i) {
        ok = ok && (0 <= tar[i] && tar[i] <= lim);
      }
      if (ok) {
        const auto slw = slow(ini, tar);
        const auto fst = fast(ini, tar);
        if (kv.second != slw || kv.second != fst) {
          cerr << ini << " " << tar << ": " << kv.second << " " << slw << " " << fst << endl;
        }
        assert(kv.second == slw);
        assert(kv.second == fst);
      }
    }
  }
}

int main() {
  // stress();
  
  for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
    int N;
    scanf("%d", &N);
    vector<Int> A(N); for (int i = 0; i < N; ++i) scanf("%lld", &A[i]);
    vector<Int> B(N); for (int i = 0; i < N; ++i) scanf("%lld", &B[i]);
    
    const Int ans = fast(A, B);
    printf("%lld\n", ans);
  }
#ifndef LOCAL
  break;
#endif
  }
  return 0;
}

詳細信息

Test #1:

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

input:

2
5
1 1 1 1 1
2 0 2 0 2
7
3 1 2 3 2 1 4
2 0 0 0 0 0 2

output:

3
3

result:

ok 2 tokens

Test #2:

score: -100
Wrong Answer
time: 130ms
memory: 5016kb

input:

110121
5
0 0 0 0 0
1 4 5 4 1
5
1 0 0 0 0
0 6 8 6 1
5
2 0 0 0 0
4 4 1 3 6
5
3 0 0 0 0
5 1 1 7 6
5
4 0 0 0 0
6 8 7 0 8
5
5 0 0 0 0
5 9 7 7 5
5
6 0 0 0 0
9 2 2 8 0
5
7 0 0 0 0
9 4 7 0 9
5
8 0 0 0 0
6 7 3 7 5
5
9 0 0 0 0
4 0 9 1 4
5
0 1 0 0 0
0 6 6 3 0
5
1 1 0 0 0
3 4 3 4 9
5
2 1 0 0 0
0 4 0 1 4
5
3 1 0...

output:

-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
...

result:

wrong answer 19126th words differ - expected: '17', found: '15'