QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#239553#7686. The Phantom Menaceucup-team1191#WA 462ms142556kbC++206.2kb2023-11-04 21:18:552023-11-04 21:18:55

Judging History

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

  • [2024-10-08 14:11:03]
  • hack成功,自动添加数据
  • (/hack/941)
  • [2024-10-08 10:05:28]
  • hack成功,自动添加数据
  • (/hack/940)
  • [2024-10-07 19:51:15]
  • hack成功,自动添加数据
  • (/hack/938)
  • [2024-10-07 19:28:01]
  • hack成功,自动添加数据
  • (/hack/937)
  • [2024-10-07 17:16:32]
  • hack成功,自动添加数据
  • (/hack/936)
  • [2024-10-07 16:53:09]
  • hack成功,自动添加数据
  • (/hack/935)
  • [2024-10-07 16:22:17]
  • hack成功,自动添加数据
  • (/hack/934)
  • [2023-11-04 21:18:55]
  • 评测
  • 测评结果:WA
  • 用时:462ms
  • 内存:142556kb
  • [2023-11-04 21:18:55]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)

// если модуль подается на вход, убрать все <> и раскомментировать нужные строки
using uint = unsigned int;
using ull = unsigned long long;
template <uint MD> struct ModInt {
    using M = ModInt;
    // static int MD;
    uint v;
    ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(uint((ull)v * r.v % MD)); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    bool operator!=(const M& r) const { return v != r.v; }
    M inv() const;
    friend istream& operator>>(istream& is, M& r) { ll x; is >> x; r = M(x); return is; }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};

template<uint MD>
ModInt<MD> pow(ModInt<MD> x, ll n) {
    ModInt<MD> r = 1;
    while (n) {
        if (n & 1) r *= x;
        x *= x;
        n >>= 1;
    }
    return r;
}

template<uint MD>
ModInt<MD> ModInt<MD>::inv() const { return pow(*this, MD - 2); }
// or copy egcd and {return egcd(MD, v, 1).second;}

// if MD is from input
// this line is necessary, read later as you wish
// int ModInt::MD;

const int MOD = 998'244'353;
using Mint = ModInt<MOD>;
// using Mint = double;

const Mint B1 = Mint(31);
const ll B2 = 239;

const int M = 1e6 + 239;

Mint pw1[M];
ll pw2[M];

string s[2][M];
string tot[2];
Mint pref1[2][M];
ll pref2[2][M];

ll gethash(int x, int l, int r) {
    Mint res1 = pref1[x][r] - pref1[x][l] * pw1[r - l];
    ll res2 = pref2[x][r] - pref2[x][l] * pw2[r - l];
    return res2 ^ (ll)(res1.v);
}

pair<int, int> e[2 * M];
vector<int> g[2 * M];  // g[i] contains indices of edges from i in e
bool ue[2 * M];
vector<int> edges;
int ind[2 * M];

void go(int v, int eid = -1) {
    while (ind[v] + 1 < g[v].size()) {
        if (!ue[g[v][++ind[v]]]) {
            ue[g[v][ind[v]]] = true;
            go(e[g[v][ind[v]]].first ^ e[g[v][ind[v]]].second ^ v, g[v][ind[v]]);
        }
    }
    if (eid != -1)
        edges.push_back(eid);
}

void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < 2; i++) {
        tot[i] = "";
        for (int j = 0; j < n; j++) {
            cin >> s[i][j];
            tot[i] += s[i][j];
        }
    }
    for (int x = 0; x < 2; x++) {
        pref1[x][0] = 0;
        pref2[x][0] = 0;
        for (int i = 0; i < n * m; i++) {
            pref1[x][i + 1] = B1 * pref1[x][i] + (tot[x][i] - 'a' + 1);
            pref2[x][i + 1] = B2 * pref2[x][i] + (tot[x][i] - 'a' + 1);
        }
    }
    for (int d = 0; d < m; d++) {
        vector<ll> L1(n), R1(n);
        vector<ll> L2(n), R2(n);
        for (int i = 0; i < n; i++) {
            L1[i] = gethash(0, i * m, i * m + d);
            R1[i] = gethash(0, i * m + d, i * m + m);
        }
        for (int i = 0; i < n; i++) {
            L2[i] = gethash(1, i * m, i * m + m - d);
            R2[i] = gethash(1, i * m + m - d, i * m + m);
        }
        vector<ll> vx;
        vx.resize(2 * n);
        vector<ll> vy;
        vy.resize(2 * n);
        for (int i = 0; i < n; i++) {
            vx[i] = L1[i];
            vx[i + n] = R2[i];
            vy[i] = R1[i];
            vy[i + n] = L2[i];
        }
        sort(vx.begin(), vx.end());
        vx.resize(unique(vx.begin(), vx.end()) - vx.begin());
        sort(vy.begin(), vy.end());
        vy.resize(unique(vy.begin(), vy.end()) - vy.begin());
        for (int i = 0; i < n; i++) {
            int s = lower_bound(vx.begin(), vx.end(), L1[i]) - vx.begin();
            int f = lower_bound(vy.begin(), vy.end(), R1[i]) - vy.begin();
            f += vx.size();
            e[i] = {s, f};
        }
        for (int i = 0; i < n; i++) {
            int f = lower_bound(vx.begin(), vx.end(), R2[i]) - vx.begin();
            int s = lower_bound(vy.begin(), vy.end(), L2[i]) - vy.begin();
            s += vx.size();
            e[i + n] = {s, f};
        }
        vector<int> indeg(vx.size() + vy.size());
        for (int i = 0; i < 2 * n; i++) {
            indeg[e[i].first]++;
            indeg[e[i].second]--;
        }
        bool ok = true;
        for (int i = 0; i < (int)indeg.size(); i++) {
            if (indeg[i] != 0) {
                ok = false;
            }
        }
        if (ok) {
            edges.clear();
            for (int i = 0; i < 2 * n; i++) {
                g[i].clear();
                ind[i] = -1;
                ue[i] = false;
            }
            for (int i = 0; i < 2 * n; i++) {
                g[e[i].first].emplace_back(i);
            }
            for (int i = 0; i < (int)indeg.size(); i++) {
                go(i);
            }
            for (int i : edges) {
                if (i < n) {
                    cout << i + 1 << " ";
                }
            }
            cout << "\n";
            for (int i : edges) {
                if (i >= n) {
                    cout << i - n + 1 << " ";
                }
            }
            cout << "\n";
            return;
        }
    }
    cout << "-1\n";
}

int main() {
#ifdef ONPC
    freopen("input", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    pw1[0] = 1;
    pw2[0] = 1;
    for (int i = 1; i < M; i++) {
        pw1[i] = pw1[i - 1] * B1;
        pw2[i] = pw2[i - 1] * B2;
    }

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

    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 20ms
memory: 141668kb

input:

2
3 3
abc
ghi
def
bcd
efg
hia
1 3
abc
def

output:

3 2 1 
2 3 1 
-1

result:

ok 2 cases (2 test cases)

Test #2:

score: -100
Wrong Answer
time: 462ms
memory: 142556kb

input:

1000000
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
...

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 not cyclic isomorphism (test case 2)