QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#856781#9970. Looping RPSIllusionaryDominance#WA 502ms32488kbC++203.2kb2025-01-14 16:22:102025-01-14 16:22:10

Judging History

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

  • [2025-01-14 16:22:10]
  • 评测
  • 测评结果:WA
  • 用时:502ms
  • 内存:32488kb
  • [2025-01-14 16:22:10]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef __int128_t i128;

const int MAX_N = 100000 + 5;
const int MAX_M = 1000000 + 5;
const int Base = 5;
const ll P = 998244353998244347ll;

inline ll add(ll a, ll b) {return a + b < P ? a + b : a + b - P;}
inline ll mul(ll a, ll b) {return (i128)(a) * b % P;}

ll pw[MAX_M], pw2[MAX_M], ipw[MAX_M];

ll qpow(ll n) {return mul(pw2[n / (MAX_M - 1)], pw[n % (MAX_M - 1)]);}

int N, cnt[MAX_N], tot;
string str[MAX_N];
struct TrieNode{
    int sz, sum, son[3];
}node[MAX_M];
struct Hash{
    int n;
    ll ha[MAX_N];
    
    void init(const string &s) {
        n = s.size();
        for (int i = 1; i <= n; i ++) {
            ha[i] = (ha[i - 1] * Base + s[i - 1]) % P;
        }
    }
    
    ll query(int pref, int len) {
        int k = len / pref, r = len % pref;
        // pw[r] * (k times pref) + ha[r]
        // k times pref : ha[pref] * (pw[k*pref] - 1) * ipw[pref]
        return add(mul(mul(mul(ha[pref], ipw[pref]), add(qpow(1ll * k * pref), P - 1)), pw[r]), ha[r]);
    }
}ha;
map <pair <ll, int>, int> status;
ll ans;

void ins(const string &s) {
    int u = 0, len = 0;
    for (auto x : s) {
        len ++;
        int y = x != 1, z = 3 - x - y;
        ans += 1ll * node[node[u].son[y]].sum * node[node[u].son[z]].sum;
        status[pair((ll)len, y)] = node[node[u].son[y]].sum;
        status[pair((ll)len, z)] = node[node[u].son[z]].sum;
        int &v = node[u].son[x]; v = v ? v : ++ tot;
        cnt[len] = node[v].sz; node[u = v].sum ++;
    }
    node[u].sz ++;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    static int Map[128];
    Map['K'] = 0;
    Map['N'] = 1;
    Map['P'] = 2;
    pw[0] = 1; pw2[0] = 1;
    auto power = [&](ll a, ll n) -> ll {
        ll ans = 1;
        while (n) {
            if (n & 1) ans = mul(ans, a);
            a = mul(a, a); n >>= 1;
        }
        return ans;
    };
    for (int i = 1; i < MAX_M; i ++) {
        pw[i] = pw[i - 1] * Base % P;
        ipw[i] = power(add(pw[i], P - 1), P - 2);
    }
    for (int i = 1; i < MAX_M; i ++) {
        pw2[i] = mul(pw2[i - 1], pw[MAX_M - 1]);
    }
    
    cin >> N;
    for (int i = 1; i <= N; i ++) {
        cin >> str[i];
        for (auto &x : str[i]) x = Map[x];
    }
    sort(str + 1, str + N + 1, [&](const string &i, const string &j) -> bool {return i.size() < j.size();});
    for (int i = 1; i <= N; i ++) {
        status.clear();
        ins(str[i]);
        ha.init(str[i]);
        for (int j = 1; j < str[i].size(); j ++) {
            ll l = j + 1, r = 1ll * j * str[i].size() + 1;
            while (l < r) {
                ll mid = l + r >> 1;
                if (ha.query(j, mid) == ha.query(str[i].size(), mid)) l = mid + 1;
                else r = mid;
            }
            l --;
            if (l >= 1ll * j * str[i].size()) continue;
            int x = str[i][l % str[i].size()], y = str[i][l % j], z = 3 - x - y;
            ans += 1ll * status[pair(l, z)] * cnt[j];
            status[pair(l, y)] += cnt[j];
        }
    }
    cout << ans << '\n';
    
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 502ms
memory: 32044kb

input:

6
P
PN
KK
N
PKK
PN

output:

6

result:

ok 1 number(s): "6"

Test #2:

score: -100
Wrong Answer
time: 501ms
memory: 32488kb

input:

10
KKKNP
KNKPPKNK
KNKPP
KNKPPKN
KKKN
NNKNNNKNNNKNNNKNNNKNNNKNNNKNNPN
NNKN
NPPN
NNKNNNKNNNKNNNKNNNKNNNKNNNK
KKKNN

output:

2

result:

wrong answer 1st numbers differ - expected: '3', found: '2'