QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#42735#4422. Two Permutations01shijian#WA 748ms47552kbC++175.7kb2022-08-03 16:46:052022-08-03 16:46:07

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-08-03 16:46:07]
  • 评测
  • 测评结果:WA
  • 用时:748ms
  • 内存:47552kb
  • [2022-08-03 16:46:05]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#ifdef LOCAL
  #include <debugger>
  clock_t start = clock();
#else
  #define debug(...) 42
#endif

template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }



mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

constexpr int N = 6E5 + 10;

using ull = unsigned long long;
using Hash = pair<unsigned long long, unsigned long long> ;
 
constexpr Hash mod = {1000000009, 1000000007};
constexpr int mod2 = 998244353;
Hash operator*(const Hash &a, const Hash &b) {
  return {(a.first * b.first) % mod.first, 
					(a.second * b.second) % mod.second};
}
 
Hash operator+(const Hash &a, const Hash &b) {
  return {(a.first + b.first) % mod.first, (a.second + b.second) % mod.second};
}
 
Hash operator-(const Hash &a, const Hash &b) {
  return {(a.first - b.first + mod.first) %  mod.first, (a.second - b.second + mod.second) % mod.second};
  // return {((a.first % mod.first) + mod.first - (b.first % mod.first)) % mod.first, 
  //         ((a.second % mod.second) + mod.second - (b.second % mod.second)) % mod.second};
}
 
Hash operator*(const Hash &a, const ull &b) {
  return {(a.first * b) % mod.first, (a.second * b) % mod.second};
}


int a[N], b[N], c[N];
int l[N], r[N];
ll f[N];
Hash base, HH[N];
Hash A[N], B[N], C[N];
int idx[N];
bool vis[N];
Hash get(Hash h[], int l, int r) {
  if(l > r) return HH[0];
  return h[r] - (h[l - 1] * HH[r - l + 1]);
}

void solve() {
  //对于一个数字的最后一次出现的位置
  //那么这个数字在原来的数组中的两个位置之前的数字一定都出现已经用过了

  //f[i] 表示 用完A的前i个,并且此时方案合法,
  int n; cin >> n;
  for(int i = 1; i <= n; i ++ ) cin >> a[i];
  for(int i = 1; i <= n; i ++ ) cin >> b[i], l[i] = 0, r[i] = 0;
  for(int i = 1; i <= n * 2; i ++ ) {
    cin >> c[i];
    if(l[c[i]]) r[c[i]] = i;
    else l[c[i]] = i;
    idx[i] = 0;
    vis[i] = false;
  }

  

  for(int i = 1; i <= n; i ++ ) {
    if(r[a[i]] == 0 || r[b[i]] == 0) {
      cout << "0\n";
      return;
    }
  }

  base = {rng() % mod.first, rng() % mod.second};

  HH[0] = A[0] = B[0] = C[0] = {1, 1};

  for(int i = 1; i <= n * 2; i ++ ) {
    HH[i] = HH[i - 1] * base ;
  }

  for(int i = 1; i <= n; i ++ ) {
    A[i] = A[i - 1] * base + A[0] * a[i];
    B[i] = B[i - 1] * base + B[0] * b[i];
  }


  for(int i = 1; i <= n * 2; i ++ ) {
    C[i] = C[i - 1] * base + C[0] * c[i];
  }


  

  for(int i = 1; i <= n; i ++ ) {
    int x = a[i];
    int left = l[x], right = r[x];
    if(i != 1) {
      int lleft = l[a[i - 1]], lright = r[a[i - 1]];
      if(vis[lleft]) {
        if(left > lleft) {
          if(get(C, lleft + 1, left - 1) == get(B, idx[lleft] + 1, left - 1 - lleft + idx[lleft])) {
            // debug(i, idx[lleft] + 1, left - 3 - lleft - idx[lleft]);
            f[left] += f[lleft];
            f[left] %= mod2;
            vis[left] = true;
            idx[left] = idx[lleft] + left - lleft - 1;
            // debug(left, lleft, idx[left]);
            // idx[left] = left - 3 - lleft - idx[lleft];
          }
          
        }

        if(right > lleft) {
          if(get(C, lleft + 1, right - 1) == get(B, idx[lleft] + 1, right - 1 - lleft + idx[lleft])) {
            f[right] += f[lleft];
            f[right] %= mod2;
            vis[right] = true;
            idx[right] = idx[lleft] + right - lleft - 1;
            
            // idx[right] = right - 3 - lleft - idx[lleft];
          }
        }
      }

      if(vis[lright]) {
        if(left > lright) {
          if(get(C, lright + 1, left - 1) == get(B, idx[lright] + 1, left - 1 - lright + idx[lright])) {
            f[left] += f[lright];
            f[left] %= mod2;
            // idx[left] = left - 3 - lright - idx[lright];
            idx[left] = idx[lright]  + left - lright - 1;
            // debug(right, left, )
            vis[left] = true;
          }
          
        }

        if(right > lright) {
          // debug(idx[lright] + 1);
          // debug(lright + 1, right - 1, idx[lright] + 1, right - 1 - lright + idx[lright]);
          if(get(C, lright + 1, right - 1) == get(B, idx[lright] + 1, right - 1 - lright + idx[lright])) {
            f[right] += f[lright];
            f[right] %= mod2;
            vis[right] = true;
            idx[right] = idx[lright]  + right - lright - 1;
            // debug(right, lright, idx[right]);
            // idx[right] = right - 3 - lright - idx[lright];
          }
        }
      }
    } else {
      
      if(get(C, 1, left - 1) == get(B, 1, left - 1)) {
        f[left] = 1;
        idx[left] = left - 1;
        vis[left] = 1;
      }
      if(get(C, 1, right - 1) == get(B, 1, right - 1)) {
        f[right] = 1;
        idx[right] = right - 1;
        vis[right] = 1;
      }
      
    }
    // cout << f[left] << " " << f[right] << "\n";
    // debug(left, right, f[left], f[right], idx[left], idx[right]);
  }
  ll ans = 0;
  if(get(C, l[a[n]] + 1, 2 * n) == get(B, idx[l[a[n]]] + 1, n)) {
    ans += f[l[a[n]]];
  }
  if(get(C, r[a[n]] + 1, 2 * n) == get(B, idx[r[a[n]]] + 1, n)) {
    ans += f[r[a[n]]];
  }
  ans %= mod2;
  cout << ans << "\n";
  // cout << (f[l[a[n]]] + f[r[a[n]]]) % mod2 << "\n";


}
int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  int T ; cin >> T;
  while(T -- )
  solve();
#ifdef LOCAL
  clock_t ends = clock();
  // cout << "\n\nRunning Time : " << (double) (ends - start) / CLOCKS_PER_SEC * 1000 << "ms" << endl;
#endif
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 748ms
memory: 47552kb

input:

282
1000
434 697 735 906 614 835 227 800 116 98 776 601 110 371 262 452 608 368 719 717 241 572 203 410 440 749 604 457 516 637 488 691 841 493 418 307 745 499 833 789 819 179 357 288 129 954 29 391 80 389 771 613 653 747 928 570 518 1000 547 587 727 778 669 554 426 899 256 681 515 532 409 677 533 3...

output:

4
1408
466650
88325712
959015061
711958793
793706912
319018029
647890815
355051771
489591573
172781746
391315416
865970289
932814894
214161857
212357590
247819964
697183431
809615918
522389119
893369114
573932447
36975589
597293540
702369197
827843023
15069337
476910212
281585445
262567522
344060519...

result:

wrong answer 2nd lines differ - expected: '2', found: '1408'