QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#855423#9970. Looping RPSucup-team3691#WA 1ms4640kbC++204.8kb2025-01-12 20:25:222025-01-12 20:25:22

Judging History

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

  • [2025-01-12 20:25:22]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:4640kb
  • [2025-01-12 20:25:22]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using namespace chrono;

using ll = long long;
using ull = unsigned long long;

string to_string(const string &s) {
  return '"' + s + '"';
}

string to_string(bool b) {
  return b ? "true" : "false";
}

template <typename A, typename B>
string to_string(const pair<A, B> &p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename T>
string to_string(const T &v) {
  string s = "{";
  bool first = true;
  for (const auto &it : v) {
    if (!first)
      s += ", ";
    else
      first = false;
    s += to_string(it);
  }
  return s += "}";
}

void debug_out() {
  cerr << endl;
}

template <typename T, typename... Args>
void debug_out(const T &first, const Args&... rest) {
  cerr << to_string(first) << " ";
  debug_out(rest...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

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

auto startTime = high_resolution_clock::now();
int get_time() {
  auto stopTime = chrono::high_resolution_clock::now();
  auto duration = duration_cast<milliseconds>(stopTime - startTime);
  return duration.count(); // in ms
}

const int DIM = 1000;

int get_val(char ch) {
  if (ch == 'P')
    return 0;

  if (ch == 'K')
    return 1;

  return 2;
}

int get_beats(int x) {
  if (x == 0)
    return 1;

  if (x == 1)
    return 2;

  return 0;
} 

struct Trie {
  int cnt = 0;
  Trie *sons[3] = {nullptr};

  void add(string &s, int x = 0) {
    ++cnt;
    if (x == s.size()) {
      return;
    }

    int i = get_val(s[x]);
    
    if (sons[i] == nullptr) {
      sons[i] = new Trie;
    }

    sons[i]->add(s, x + 1);
  }

  pair<ll, ll> get(string &s, int x = 0) {
    if (x == s.size())
      return {0, 0};

    int i = get_val(s[x]);
    int j = get_beats(i);
    int k = 3 - i - j; 

    ll better = 0, worse = 0; 
    if (sons[j] != nullptr) {
      better += sons[j]->cnt;
    }

    if (sons[k] != nullptr) {
      worse += sons[k]->cnt;
    }
    
    auto r = sons[i]->get(s, x + 1);
    better += r.first;
    worse += r.second;
    return {better, worse};
  }
};

vector<int> kmp(string &s) {
  vector<int> pi(s.size(), -1);
  for (int i = 1; i < s.size(); ++i) {
    if (i > 0)
      pi[i] = pi[i - 1];

    while (pi[i] >= 0 && s[pi[i] + 1] != s[i])
      pi[i] = pi[pi[i]];

    if (s[pi[i] + 1] == s[i]) {
      ++pi[i];
    }
  }

  return pi;
}

void solve() {
  int n;
  cin >> n;

  Trie T;
  vector<string> v(n);
  vector<string> v2(n);
  for (int i = 0; i < n; ++i) {
    string s;
    cin >> s;

    auto pi = kmp(s);
    int per = s.size() - pi[s.size() - 1] - 1;
    if (s.size() % per == 0) {
      s = s.substr(0, per);
    }
    v[i] = s;
  }

  sort(v.begin(), v.end());

  for (int i = 0; i < n; ++i) {
    auto &s = v[i];
    if (s.size() < DIM) {
      int rep = (2 * DIM + s.size() - 1) / s.size();
      string s2;
      while (rep--) {
        for (auto it : s)
          s2.push_back(it);
      }
      v2[i] = s2;
      T.add(s2);
    }
  }

  // TODO siruri egale
  ll ans = 0;
  vector<int> st(n), dr(n);
  for (int i = 0, j = 0; i < n; i = j + 1) {
    j = i;
    while (j < n && v[j] == v[i]) {
      ++j;
    }
    --j;
    for (int k = i; k <= j; ++k) {
      st[k] = i;
      dr[k] = j;
    }
    ans = ans + 1LL * (j - i + 1) * (j - i) * (j - i - 1) / 6; // triplete egale
  }

  vector<ll> b(n, 0), w(n, 0);
  for (int i = 0; i < n; ++i) {
    if (v[i].size() < DIM){
      auto [better, worse] = T.get(v2[i]);
      b[i] += better;
      w[i] += worse;
      continue;
    } else {
      int better = 0;
      int worse = 0;
      for (int j = 0; j < n; ++j) {
        if (st[i] <= j && j <= dr[i])
          continue;

        if (j < i && v[j].size() >= DIM)
          continue;

        for (int l1 = 0, l2 = 0; ; ++l1, ++l2) {
          if (l1 == v[i].size())
            l1 = 0;
          if (l2 == v[j].size())
            l2 = 0;

          if (v[i][l1] != v[j][l2]) {
            if (get_beats(get_val(v[i][l1])) == get_val(v[j][l2])) {
              ++b[i];
              ++w[j];
            } else {
              ++w[i];
              ++b[j];
            }
            break;
          }
        }
      }

    }
  }

  for (int i = 0; i < n; ++i) {
    int better = b[i];
    int worse = w[i];
    ans = ans + 1LL * better * (better - 1) / 2;
    if (i == st[i])
      ans = ans + 1LL * worse * (dr[i] - st[i]) * (dr[i] - st[i] + 1) / 2;
  }


  ans = 1LL * n * (n - 1) * (n - 2) / 6 - ans;
  cout << ans << "\n";
}

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

  int t = 1;
//  cin >> t;
  while (t--)
    solve();

  return 0;
}

详细

Test #1:

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

input:

6
P
PN
KK
N
PKK
PN

output:

6

result:

ok 1 number(s): "6"

Test #2:

score: 0
Accepted
time: 0ms
memory: 4596kb

input:

10
KKKNP
KNKPPKNK
KNKPP
KNKPPKN
KKKN
NNKNNNKNNNKNNNKNNNKNNNKNNNKNNPN
NNKN
NPPN
NNKNNNKNNNKNNNKNNNKNNNKNNNK
KKKNN

output:

3

result:

ok 1 number(s): "3"

Test #3:

score: 0
Accepted
time: 1ms
memory: 4640kb

input:

10
NNNPNNNPNNNPNNNK
KKN
NNNP
KKP
NNNPNNNPNNNPN
KKNKKNKKPN
KNNPNPNKKKNPPKNKKKNKNKKNKPPPNKKPKP
KKPK
KKNKKNK
KKPKKN

output:

3

result:

ok 1 number(s): "3"

Test #4:

score: -100
Wrong Answer
time: 1ms
memory: 4292kb

input:

10
K
PPPNNPPPNNPPPNNPPPNNPPPNNPPPNNPPPNNPPPNNP
PPKP
PPPNNPPPNNPPPNNPPPNNPPPNNPPPNNPPPNNPPPNNPPPK
P
K
N
P
PPPNN
N

output:

23

result:

wrong answer 1st numbers differ - expected: '25', found: '23'