QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#383198#5414. Stop, Yesterday Please No MoreshepherdTL 491ms106516kbC++208.8kb2024-04-09 03:40:092024-04-09 03:40:09

Judging History

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

  • [2024-04-09 03:40:09]
  • 评测
  • 测评结果:TL
  • 用时:491ms
  • 内存:106516kb
  • [2024-04-09 03:40:09]
  • 提交

answer

#include <bits/stdc++.h>

#include <vector>

#pragma GCC optimize("O3,unroll-loops")

#ifdef LLOCAL
#include "debug.h"
#else
#define var(...)
#define debugArr(...)
#endif

using namespace std;

#define len(a) static_cast<int>((a).size())
#define present(c, x) (c.find(x) != c.end())
#define printDecimal(d) std::cout << std::setprecision(d) << std::fixed

using ll = long long;
using ull = unsigned long long;
using ld = long double;
constexpr const int iinf = 1e9 + 7;
constexpr const ll inf = 1e18;
constexpr const ll mod = 1'000'000'007;

template <typename Fun>
class y_combinator_result {
  Fun fun_;

 public:
  template <typename T>
  explicit y_combinator_result(T&& fun) : fun_(std::forward<T>(fun)) {}

  template <typename... Args>
  decltype(auto) operator()(Args&&... args) {
    return fun_(std::ref(*this), std::forward<Args>(args)...);
  }
};
template <typename Fun>
decltype(auto) y_combinator(Fun&& fun) {
  return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
}

pair<vector<vector<int>>, int> construct_grid(int n, int m, const string& s) {
  vector<vector<int>> grid_2d(n, vector<int>(m));
  int u = 0, l = 0, r = m - 1, d = n - 1;
  int bu = 0, bl = 0, br = m - 1, bd = n - 1;
  for (auto c : s) {
    switch (c) {
      case 'U': {
        if (bu == u) {
          bu++;
        }
        u++, d++;
        break;
      }
      case 'L': {
        if (bl == l) {
          bl++;
        }
        l++, r++;
        break;
      }
      case 'R': {
        if (br == r) {
          br--;
        }
        r--, l--;
        break;
      }
      case 'D': {
        if (bd == d) {
          bd--;
        }
        d--, u--;
        break;
      }
      default: {
        assert(false);
      }
    }
  }
  int oob = n * m;
  if (bu <= bd && bl <= br) {
    for (int i = bu; i <= bd; i++) {
      for (int j = bl; j <= br; j++) {
        grid_2d[i][j] = 1;
        oob--;
      }
    }
  }
  return make_pair(grid_2d, oob);
}

vector<ll> flatten_and_cast(const vector<vector<int>>& grid) {
  vector<ll> ret;
  for (const auto& elem : grid) {
    for (auto& x : elem) {
      ret.push_back(x);
    }
  }
  return ret;
}

struct motif_data {
  vector<vector<int>> motif;
  int px, py, mn, mm;
};

motif_data construct_motif(int n, int m, const string& s) {
  int px = 0, py = 0, cx = 0, cy = 0;
  for (auto c : s) {
    switch (c) {
      case 'D': {
        if (cx == 0)
          px++;
        else
          cx--;
        break;
      }
      case 'U': {
        cx++;
        break;
      }
      case 'R': {
        if (cy == 0)
          py++;
        else
          cy--;
        break;
      }
      case 'L': {
        cy++;
        break;
      }
    }
  }
  vector<vector<int>> motif(px + 1, vector<int>(py + 1));
  motif[cx = px][cy = py] = 1;
  int num_col = py + 1;
  for (auto c : s) {
    switch (c) {
      case 'D': {
        cx--;
        assert(cx >= 0);
        break;
      }
      case 'U': {
        cx++;
        break;
      }
      case 'L': {
        cy++;
        break;
      }
      case 'R': {
        cy--;
        assert(cy >= 0);
        break;
      }
      default: {
        assert(false);
      }
    }
    while (len(motif) <= cx) motif.emplace_back();
    while (len(motif[cx]) <= cy) motif[cx].push_back(0);
    motif[cx][cy] = 1;
    num_col = max(num_col, cy + 1);
  }
  for (int i = 0; i < len(motif); i++) {
    while (len(motif[i]) < num_col) motif[i].push_back(0);
  }
  return motif_data{motif, px, py, len(motif), num_col};
}

vector<vector<int>> pad_grid(const vector<vector<int>>& grid, int pt, int pb,
                             int pl, int pr) {
  vector<vector<int>> ret;
  for (int i = 0; i < pt; i++) {
    ret.emplace_back();
    for (int j = 0; j < pl; j++) {
      ret.back().push_back(0);
    }
    for (int j = 0; j < len(grid[0]); j++) {
      ret.back().push_back(0);
    }
    for (int j = 0; j < pr; j++) {
      ret.back().push_back(0);
    }
  }
  for (int i = 0; i < len(grid); i++) {
    ret.emplace_back();
    for (int j = 0; j < pl; j++) {
      ret.back().push_back(0);
    }
    for (int j = 0; j < len(grid[i]); j++) {
      ret.back().push_back(grid[i][j]);
    }
    for (int j = 0; j < pr; j++) {
      ret.back().push_back(0);
    }
  }
  for (int i = 0; i < pb; i++) {
    ret.emplace_back();
    for (int j = 0; j < pl; j++) {
      ret.back().push_back(0);
    }
    for (int j = 0; j < len(grid[0]); j++) {
      ret.back().push_back(0);
    }
    for (int j = 0; j < pr; j++) {
      ret.back().push_back(0);
    }
  }
  return ret;
}

namespace kactl {
// typedef vector<ll> vl;
// typedef complex<double> C;
// void fft(vector<C>& a) {
//   int n = len(a), L = 31 - __builtin_clz(n);
//   static vector<complex<long double>> R(2, 1);
//   static vector<C> rt(2, 1);  // (^ 10% faster if double)
//   for (static int k = 2; k < n; k *= 2) {
//     R.resize(n);
//     rt.resize(n);
//     auto x = polar(1.0L, acos(-1.0L) / k);
//     for (int i = k; i < 2 * k; i++)
//       rt[i] = R[i] = i & 1 ? R[i / 2] * x : R[i / 2];
//   }
//   vector<int> rev(n);
//   for (int i = 0; i < n; i++) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
//   for (int i = 0; i < n; i++)
//     if (i < rev[i]) swap(a[i], a[rev[i]]);
//   for (int k = 1; k < n; k *= 2)
//     for (int i = 0; i < n; i += 2 * k)
//       for (int j = 0; j < k; j++) {
//         // C z = rt[j+k] * a[i+j+k]; // (25% faster if hand-rolled)  ///
//         // include-line
//         auto x = (double*)&rt[j + k],
//              y = (double*)&a[i + j + k];  /// exclude-line
//         C z(x[0] * y[0] - x[1] * y[1],
//             x[0] * y[1] + x[1] * y[0]);  /// exclude-line
//         a[i + j + k] = a[i + j] - z;
//         a[i + j] += z;
//       }
// }
// vector<double> conv(const vector<double>& a, const vector<double>& b) {
//   if (a.empty() || b.empty()) return {};
//   vector<double> res(len(a) + len(b) - 1);
//   int L = 32 - __builtin_clz(len(res)), n = 1 << L;
//   vector<C> in(n), out(n);
//   copy(begin(a), end(a), begin(in));
//   for (int i = 0; i < len(b); i++) in[i].imag(b[i]);
//   fft(in);
//   for (C& x : in) x *= x;
//   for (int i = 0; i < n; i++) out[i] = in[-i & (n - 1)] - conj(in[i]);
//   fft(out);
//   for (int i = 0; i < len(res); i++) res[i] = imag(out[i]) / (4 * n);
//   return res;
// }
using cd = complex<double>;
const double PI = acos(-1);
void fft(vector<cd>& a, bool invert) {
  int n = a.size();

  for (int i = 1, j = 0; i < n; i++) {
    int bit = n >> 1;
    for (; j & bit; bit >>= 1) j ^= bit;
    j ^= bit;

    if (i < j) swap(a[i], a[j]);
  }

  for (int len = 2; len <= n; len <<= 1) {
    double ang = 2 * PI / len * (invert ? -1 : 1);
    cd wlen(cos(ang), sin(ang));
    for (int i = 0; i < n; i += len) {
      cd w(1);
      for (int j = 0; j < len / 2; j++) {
        cd u = a[i + j], v = a[i + j + len / 2] * w;
        a[i + j] = u + v;
        a[i + j + len / 2] = u - v;
        w *= wlen;
      }
    }
  }

  if (invert) {
    for (cd& x : a) x /= n;
  }
}
vector<ll> conv(const vector<ll>& a, const vector<ll>& b) {
  vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end());
  int n = 1;
  while (n < a.size() + b.size()) n <<= 1;
  fa.resize(n);
  fb.resize(n);

  fft(fa, false);
  fft(fb, false);
  for (int i = 0; i < n; i++) fa[i] *= fb[i];
  fft(fa, true);

  vector<ll> result(n);
  for (int i = 0; i < n; i++) result[i] = round(fa[i].real());
  return result;
}
}  // namespace kactl

int main() {
  std::ios_base::sync_with_stdio(false);
  cin.tie(0);
  int t;
  cin >> t;
  while (t--) {
    int n, m, k;
    cin >> n >> m >> k;
    string s;
    cin >> s;
    auto [grid, oob] = construct_grid(n, m, s);
    auto [motif, px, py, mn, mm] = construct_motif(n, m, s);
    int pad_bottom = 0, pad_right = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        pad_bottom = max(pad_bottom, i + mn - px - 1 - len(grid) + 1);
        pad_right = max(pad_right, j + mm - py - 1 - len(grid[0]) + 1);
      }
    }
    grid = pad_grid(grid, px, pad_bottom, py, pad_right);
    int target = n * m - oob - k;
    if (target < 0) {
      cout << 0 << '\n';
      continue;
    }
    n = len(grid), m = len(grid[0]);
    for (int i = 0; i < len(motif) - 1; i++) {
      while (len(motif[i]) < m) motif[i].push_back(0);
    }
    auto grid_1d = flatten_and_cast(grid);
    auto motif_1d = flatten_and_cast(motif);
    reverse(motif_1d.begin(), motif_1d.end());
    auto d = kactl::conv(grid_1d, motif_1d);
    int ret = 0;
    for (int i = 0; i + mn <= n; i++) {
      for (int j = 0; j + mm <= m; j++) {
        ret += (fabs(d[i * m + j + len(motif_1d) - 1] - target) <= 1e-8);
      }
    }
    cout << ret << '\n';
  }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

3
4 5 3
ULDDRR
4 5 0
UUUUUUU
4 5 10
UUUUUUU

output:

2
20
0

result:

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

Test #2:

score: 0
Accepted
time: 120ms
memory: 7156kb

input:

1060
19 12 0
UDLDDUUUUDDDLLRDUDUURULUUUDRDUDRDRLRLRLULULLLDLDDRLUUUURUUUDDRLLRUUUDULURUULLRDRLRDDURDUUURRRLURLRUULRRUDURDLUUURDLURDDLUUURDDRLLURRDLRUDLRDRLLRRDRDDLDRURRRLUDULLLRUUDLRRURRDLLRRRDLLRDDDLRLRURURDDDL
11 1 0
UR
3 18 33
UDRLR
17 11 132
RLDRDLDRUU
6 10 13
UULUDDLRDLUUDLDD
1 15 0
D
6 20 50
D...

output:

228
11
20
99
18
15
34
240
15
0
0
13
14
18
26
16
1
19
108
8
2
2
3
7
0
30
16
21
0
8
10
9
15
5
320
11
7
3
0
0
12
0
11
0
0
14
0
22
36
51
23
7
6
4
2
48
28
8
63
22
49
13
10
4
108
10
18
44
0
15
9
0
4
30
14
99
105
10
14
17
0
66
10
11
28
52
34
56
33
14
56
90
14
0
121
3
48
30
36
13
0
30
7
8
3
11
16
45
20
34
0...

result:

ok 1060 numbers

Test #3:

score: 0
Accepted
time: 207ms
memory: 61276kb

input:

1
1000 1000 979065
DDUULULUDULLULLDLUULURRLDURLRDLRRUURUUUDLRLUUDUUDUDLLDDDULU

output:

958416

result:

ok 1 number(s): "958416"

Test #4:

score: 0
Accepted
time: 491ms
memory: 106516kb

input:

1
1000 1000 943471
LRLDLURLDLRDRDUULULRDDLLRURDUURLLDDLDLDDLLLUUURLDRUDRLLUUUUUDLUUDLURURRDLRLRRRLULRRULURLRRDLDRLUDRRLDDLUDRRLLUDLLLRDULRRRRLDUUDRDLULUUUUDRRDULUDLLUUDLDURDRRLRRLDRLDDRURURLUULRRLDLLRLRDRRUULDLDLULLDLLRULLRUULURDURRLUUDUULLULDLRUDDLRLRLLUDDDLLLUDRRLDDULRRURRDURDDRDLLULRLULURLRDLLURD...

output:

889224

result:

ok 1 number(s): "889224"

Test #5:

score: -100
Time Limit Exceeded

input:

1
1000 1000 315808
LLRURURRDDDULLDDUDRDLRLLLDDDLUDRDURLDULRLRULUUDLUULUUDULLLLDDURLDUULUUDLLDLLDRUDUULRLLRLRUURLRLULLDDLLDUDLLRUUDRLDLUULDLLDRRRURDULLDRRRDURURDRLDURURUDLURLDURRLRRUDUDURDRLRRRDLRRURLURUDRRLDLRULLDLUURDURLURLLRDLRDRUURURDRUDUUUDLRRLUDLUUDUDDRRDUULUUDDRLLULDUUDRURRDRLULRLULDURLURUDLLD...

output:

426

result: