QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#847783#2515. Graph Cardsduongnc000AC ✓21421ms161728kbC++2324.2kb2025-01-08 11:14:122025-01-08 11:14:12

Judging History

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

  • [2025-01-08 11:14:12]
  • 评测
  • 测评结果:AC
  • 用时:21421ms
  • 内存:161728kb
  • [2025-01-08 11:14:12]
  • 提交

answer

/*
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt")
*/

#include <bits/stdc++.h>
#define taskname ""
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define i64 long long
#define u64 unsigned long long
#define isz(x) (int)x.size()
using namespace std;

template<class data_t, data_t _mod>
struct modular_fixed_base{
#define IS_INTEGRAL(T) (is_integral_v<T> || is_same_v<T, __int128_t> || is_same_v<T, __uint128_t>)
#define IS_UNSIGNED(T) (is_unsigned_v<T> || is_same_v<T, __uint128_t>)
    static_assert(IS_UNSIGNED(data_t));
    static_assert(_mod >= 1);
    static constexpr bool VARIATE_MOD_FLAG = false;
    static constexpr data_t mod(){
        return _mod;
    }
    template<class T>
    static vector<modular_fixed_base> precalc_power(T base, int SZ){
        vector<modular_fixed_base> res(SZ + 1, 1);
        for(auto i = 1; i <= SZ; ++ i) res[i] = res[i - 1] * base;
        return res;
    }    
    static vector<modular_fixed_base> _INV;
    static void precalc_inverse(int SZ){
        if(_INV.empty()) _INV.assign(2, 1);
        for(auto x = _INV.size(); x <= SZ; ++ x) _INV.push_back(_mod / x * -_INV[_mod % x]);
    }
    // _mod must be a prime
    static modular_fixed_base _primitive_root;
    static modular_fixed_base primitive_root(){
        if(_primitive_root) return _primitive_root;
        if(_mod == 2) return _primitive_root = 1;
        if(_mod == 998244353) return _primitive_root = 3;
        data_t divs[20] = {};
        divs[0] = 2;
        int cnt = 1;
        data_t x = (_mod - 1) / 2;
        while(x % 2 == 0) x /= 2;
        for(auto i = 3; 1LL * i * i <= x; i += 2){
            if(x % i == 0){
                divs[cnt ++] = i;
                while(x % i == 0) x /= i;
            }
        }
        if(x > 1) divs[cnt ++] = x;
        for(auto g = 2; ; ++ g){
            bool ok = true;
            for(auto i = 0; i < cnt; ++ i){
                if(modular_fixed_base(g).power((_mod - 1) / divs[i]) == 1){
                    ok = false;
                    break;
                }
            }
            if(ok) return _primitive_root = g;
        }
    }
    constexpr modular_fixed_base(){ }
    modular_fixed_base(const double &x){ data = _normalize(llround(x)); }
    modular_fixed_base(const long double &x){ data = _normalize(llround(x)); }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr> modular_fixed_base(const T &x){ data = _normalize(x); }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr> static data_t _normalize(const T &x){
        int sign = x >= 0 ? 1 : -1;
        data_t v =  _mod <= sign * x ? sign * x % _mod : sign * x;
        if(sign == -1 && v) v = _mod - v;
        return v;
    }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr> operator T() const{ return data; }
    modular_fixed_base &operator+=(const modular_fixed_base &otr){ if((data += otr.data) >= _mod) data -= _mod; return *this; }
    modular_fixed_base &operator-=(const modular_fixed_base &otr){ if((data += _mod - otr.data) >= _mod) data -= _mod; return *this; }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr> modular_fixed_base &operator+=(const T &otr){ return *this += modular_fixed_base(otr); }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr> modular_fixed_base &operator-=(const T &otr){ return *this -= modular_fixed_base(otr); }
    modular_fixed_base &operator++(){ return *this += 1; }
    modular_fixed_base &operator--(){ return *this += _mod - 1; }
    modular_fixed_base operator++(int){ modular_fixed_base result(*this); *this += 1; return result; }
    modular_fixed_base operator--(int){ modular_fixed_base result(*this); *this += _mod - 1; return result; }
    modular_fixed_base operator-() const{ return modular_fixed_base(_mod - data); }
    modular_fixed_base &operator*=(const modular_fixed_base &rhs){
        if constexpr(is_same_v<data_t, unsigned int>) data = (unsigned long long)data * rhs.data % _mod;
        else if constexpr(is_same_v<data_t, unsigned long long>){
            long long res = data * rhs.data - _mod * (unsigned long long)(1.L / _mod * data * rhs.data);
            data = res + _mod * (res < 0) - _mod * (res >= (long long)_mod);
        }
        else data = _normalize(data * rhs.data);
        return *this;
    }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>
    modular_fixed_base &inplace_power(T e){
        if(e == 0) return *this = 1;
        if(data == 0) return *this = {};
        if(data == 1 || e == 1) return *this;
        if(data == mod() - 1) return e % 2 ? *this : *this = -*this;
        if(e < 0) *this = 1 / *this, e = -e;
        if(e == 1) return *this;
        modular_fixed_base res = 1;
        for(; e; *this *= *this, e >>= 1) if(e & 1) res *= *this;
        return *this = res;
    }
    template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>
    modular_fixed_base power(T e) const{
        return modular_fixed_base(*this).inplace_power(e);
    }
    modular_fixed_base &operator/=(const modular_fixed_base &otr){
        make_signed_t<data_t> a = otr.data, m = _mod, u = 0, v = 1;
        if(a < _INV.size()) return *this *= _INV[a];
        while(a){
            make_signed_t<data_t> t = m / a;
            m -= t * a; swap(a, m);
            u -= t * v; swap(u, v);
        }
        assert(m == 1);
        return *this *= u;
    }
#define ARITHMETIC_OP(op, apply_op)\
modular_fixed_base operator op(const modular_fixed_base &x) const{ return modular_fixed_base(*this) apply_op x; }\
template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>\
modular_fixed_base operator op(const T &x) const{ return modular_fixed_base(*this) apply_op modular_fixed_base(x); }\
template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>\
friend modular_fixed_base operator op(const T &x, const modular_fixed_base &y){ return modular_fixed_base(x) apply_op y; }
    ARITHMETIC_OP(+, +=) ARITHMETIC_OP(-, -=) ARITHMETIC_OP(*, *=) ARITHMETIC_OP(/, /=)
#undef ARITHMETIC_OP
#define COMPARE_OP(op)\
bool operator op(const modular_fixed_base &x) const{ return data op x.data; }\
template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>\
bool operator op(const T &x) const{ return data op modular_fixed_base(x).data; }\
template<class T, typename enable_if<IS_INTEGRAL(T)>::type* = nullptr>\
friend bool operator op(const T &x, const modular_fixed_base &y){ return modular_fixed_base(x).data op y.data; }
    COMPARE_OP(==) COMPARE_OP(!=) COMPARE_OP(<) COMPARE_OP(<=) COMPARE_OP(>) COMPARE_OP(>=)
#undef COMPARE_OP
    friend istream &operator>>(istream &in, modular_fixed_base &number){
        long long x;
        in >> x;
        number.data = modular_fixed_base::_normalize(x);
        return in;
    }
//#define _SHOW_FRACTION
    friend ostream &operator<<(ostream &out, const modular_fixed_base &number){
        out << number.data;
    #if defined(LOCAL) && defined(_SHOW_FRACTION)
        cerr << "(";
        for(auto d = 1; ; ++ d){
            if((number * d).data <= 1000000){
                cerr << (number * d).data;
                if(d != 1) cerr << "/" << d;
                break;
            }
            else if((-number * d).data <= 1000000){
                cerr << "-" << (-number * d).data;
                if(d != 1) cerr << "/" << d;
                break;
            }
        }
        cerr << ")";
    #endif
        return out;
    }
    data_t data = 0;
#undef _SHOW_FRACTION
#undef IS_INTEGRAL
#undef IS_UNSIGNED
};
template<class data_t, data_t _mod> vector<modular_fixed_base<data_t, _mod>> modular_fixed_base<data_t, _mod>::_INV;
template<class data_t, data_t _mod> modular_fixed_base<data_t, _mod> modular_fixed_base<data_t, _mod>::_primitive_root;

// const unsigned int mod = (119 << 23) + 1; // 998244353
// const unsigned int mod = 1e9 + 7; // 1000000007
// const unsigned int mod = 1e9 + 9; // 1000000009
const unsigned long long mod = (unsigned long long)1e18 + 9;
using modular = modular_fixed_base<decay_t<decltype(mod)>, mod>;

template<class T>
struct graph{
    using Weight_t = T;
    struct Edge_t{
        int from, to;
        T cost;
    };
    int n;
    vector<Edge_t> edge;
    vector<vector<int>> adj;
    function<bool(int)> ignore;
    graph(int n = 1): n(n), adj(n){
        assert(n >= 1);
    }
    graph(const vector<vector<int>> &adj, bool undirected = true): n((int)adj.size()), adj(n){
        assert(n >= 1);
        if(undirected){
            for(auto u = 0; u < n; ++ u) for(auto v: adj[u]) if(u < v) link(u, v);
        }
        else for(auto u = 0; u < n; ++ u) for(auto v: adj[u]) orient(u, v);
    }
    graph(const vector<vector<pair<int, T>>> &adj, bool undirected = true): n((int)adj.size()), adj(n){
        assert(n >= 1);
        if(undirected){
            for(auto u = 0; u < n; ++ u) for(auto [v, w]: adj[u]) if(u < v) link(u, v, w);
        }
        else for(auto u = 0; u < n; ++ u) for(auto [v, w]: adj[u]) orient(u, v, w);
    }
    graph(int n, vector<array<int, 2>> &edge, bool undirected = true): n(n), adj(n){
        assert(n >= 1);
        for(auto [u, v]: edge) undirected ? link(u, v) : orient(u, v);
    }
    graph(int n, vector<tuple<int, int, T>> &edge, bool undirected = true): n(n), adj(n){
        assert(n >= 1);
        for(auto [u, v, w]: edge) undirected ? link(u, v, w) : orient(u, v, w);
    }
    int add_vertex(){
        adj.emplace_back();
        return n ++;
    }
    int operator()(int u, int id) const{
        #ifdef LOCAL
        assert(0 <= id && id < (int)edge.size());
        assert(edge[id].from == u || edge[id].to == u);
        #endif
        return u ^ edge[id].from ^ edge[id].to;
    }
    int link(int u, int v, T w = {}){ // insert an undirected edge
        int id = (int)edge.size();
        adj[u].push_back(id), adj[v].push_back(id), edge.push_back({u, v, w});
        return id;
    }
    int orient(int u, int v, T w = {}){ // insert a directed edge
        int id = (int)edge.size();
        adj[u].push_back(id), edge.push_back({u, v, w});
        return id;
    }
    vector<int> neighbor(int u, int exclude = -1) const{
        vector<int> res;
        for(auto id: adj[u]){
            if(id == exclude || ignore && ignore(id)) continue;
            res.push_back(operator()(u, id));
        }
        return res;
    }
    void clear(){
        for(auto [u, v, w]: edge){
            adj[u].clear();
            adj[v].clear();
        }
        edge.clear();
        ignore = {};
    }
    graph transpose() const{ // the transpose of the directed graph
        graph res(n);
        for(auto id = 0; id < (int)edge.size(); ++ id){
            if(ignore && ignore(id)) continue;
            res.orient(edge[id].to, edge[id].from, edge[id].cost);
        }
        return res;
    }
    int degree(int u) const{ // the degree (outdegree if directed) of u (without the ignoration rule)
        return (int)adj[u].size();
    }
    // The adjacency list is sorted for each vertex.
    vector<vector<int>> get_adjacency_list() const{
        vector<vector<int>> res(n);
        for(auto u = 0; u < n; ++ u) for(auto id: adj[u]){
            if(ignore && ignore(id)) continue;
            res[(*this)(u, id)].push_back(u);
        }
        return res;
    }
    void set_ignoration_rule(const function<bool(int)> &f){
        ignore = f;
    }
    void reset_ignoration_rule(){
        ignore = nullptr;
    }
    friend ostream &operator<<(ostream &out, const graph &g){
        for(auto id = 0; id < (int)g.edge.size(); ++ id){
            if(g.ignore && g.ignore(id)) continue;
            auto &e = g.edge[id];
            out << "{" << e.from << ", " << e.to << ", " << e.cost << "}\n";
        }
        return out;
    }
};

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

// T must be a modular type
// Requires graph
template<class T>
struct tree_hasher{
    mt19937 rng;
    vector<int> order;
    vector<T> base, hash;
    tree_hasher(): rng(chrono::high_resolution_clock::now().time_since_epoch().count()){}
    int attempt = 0;
    vector<int> was;
    template<class U>
    void run(const graph<U> &g, const vector<int> &src = {0}, bool clear_order = true){
        int n = g.n;
        ++ attempt;
        if(clear_order) order.clear();
        while(base.size() < n) base.push_back(rng());
        hash.resize(n);
        was.resize(n);
        auto dfs = [&](auto self, int u, int p)->int{
            order.push_back(u);
            was[u] = attempt;
            hash[u] = 1;
            int d = 0;
            for(auto id: g.adj[u]){
                if(g.ignore && g.ignore(id)) continue;
                int v = g(u, id);
                if(v == p) continue;
                d = max(d, self(self, v, u) + 1);
            }
            for(auto id: g.adj[u]){
                if(g.ignore && g.ignore(id)) continue;
                int v = g(u, id);
                if(v == p) continue;
                hash[u] *= base[d] + hash[v];
            }
            return d;
        };
        for(auto s: src) if(was[s] != attempt) dfs(dfs, s, -1);
    }
};

// Requires modular
template<class modular_t, class len_t, bool ALLOW_BINEXP>
struct hash_bidirectional{
#ifdef LOCAL
    #define ASSERT(c) assert(c)
#else
    #define ASSERT(c) 42
#endif
    static modular_t _base, _inv_base;
    template<class T = int>
    static void setup(T base = 0){
        if constexpr(modular_t::VARIATE_MOD_FLAG) modular_t::setup((unsigned long long)1e18 + 9);
        if(!base) base = mt19937(chrono::high_resolution_clock::now().time_since_epoch().count())() % 100'000'000 + 100'000'000;
        _base = base, _inv_base = modular_t(1) / base;
    }
    static vector<modular_t> _power, _inv_power;
    static void setup_power(size_t len){
        if(_power.empty()) _power.push_back(1), _inv_power.push_back(1);
        while((int)_power.size() <= len){
            _power.push_back(_power.back() * _base);
            _inv_power.push_back(_inv_power.back() * _inv_base);
        }
    }
    static modular_t power(len_t e){
        assert(e >= 0);
        if constexpr(ALLOW_BINEXP) return e < (int)_power.size() ? _power[e] : _base.power(e);
        else{
            if((int)_power.size() <= e) setup_power(e);
            return _power[e];
        }
    }
    static modular_t inv_power(len_t e){
        assert(e >= 0);
        if constexpr(ALLOW_BINEXP) return e < (int)_inv_power.size() ? _inv_power[e] : _inv_base.power(e);
        else{
            if((int)_power.size() <= e) setup_power(e);
            return _inv_power[e];
        }
    }
    hash_bidirectional(){ ASSERT(_base >= 1); }
    hash_bidirectional(const modular_t &x, const modular_t &y, len_t len): data(x), rev_data(y), len(len){ ASSERT(_base >= 1); }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional(T x): data(x), rev_data(x), len(1){ ASSERT(_base >= 1); }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional(const vector<T> &s){
        ASSERT(_base >= 1);
        for(auto c: s) *this += hash_bidirectional(c);
    }
    hash_bidirectional(const string &s){
        ASSERT(_base >= 1);
        for(auto c: s) *this += hash_bidirectional(c);
    }
    hash_bidirectional &inplace_flip(){
        swap(data, rev_data);
        return *this;
    }
    hash_bidirectional flip() const{ return hash_bidirectional(*this).inplace_flip(); }
    bool is_palindrome() const{ return data == rev_data; }
    hash_bidirectional &operator=(const hash_bidirectional &x){
        data = x.data, rev_data = x.rev_data, len = x.len;
        return *this;
    }
    hash_bidirectional &operator+=(const hash_bidirectional &x){
        data = power(x.len) * data + x.data;
        rev_data += power(len) * x.rev_data;
        len += x.len;
        return *this;
    }
    hash_bidirectional operator+(const hash_bidirectional &x) const{ return hash_bidirectional(*this) += x; }
    hash_bidirectional &inplace_append_right(const hash_bidirectional &x){ return *this += x; }
    hash_bidirectional append_right(const hash_bidirectional &x) const{ return hash_bidirectional(*this).inplace_append_right(x); }
    hash_bidirectional &inplace_append_left(const hash_bidirectional &x){
        data += power(len) * x.data;
        rev_data = x.rev_data + power(x.len) * rev_data;
        len += x.len;
        return *this;
    }
    hash_bidirectional append_left(const hash_bidirectional &x) const{ return hash_bidirectional(*this).inplace_append_left(x); }
    hash_bidirectional &inplace_pop_right(const hash_bidirectional &x){
        assert(len >= x.len);
        data = inv_power(x.len) * (data - x.data);
        rev_data -= power(len - x.len) * x.rev_data;
        len -= x.len;
        return *this;
    }
    hash_bidirectional pop_right(const hash_bidirectional &x) const{ return hash_bidirectional(*this).inplace_pop_right(x); }
    hash_bidirectional &inplace_pop_left(const hash_bidirectional &x){
        assert(len >= x.len);
        data -= power(len - x.len) * x.data;
        rev_data = inv_power(x.len) * (rev_data - x.rev_data);
        len -= x.len;
        return *this;
    }
    hash_bidirectional pop_left(const hash_bidirectional &x) const{ return hash_bidirectional(*this).inplace_pop_left(x); }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional &inplace_update(len_t pos, T x){
        assert(0 <= pos && pos < len);
        data += power(len - pos - 1) * x;
        rev_data += power(pos) * x;
        return *this;
    }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional update(len_t pos, T x) const{ return hash_bidirectional(*this).inplace_update(pos, x); }
    hash_bidirectional &inplace_update(len_t pos, const hash_bidirectional &x){
        assert(0 <= pos && pos + x.len <= len);
        data += power(len - pos - x.len) * x.data;
        rev_data += power(pos) * x.rev_data;
        return *this;
    }
    hash_bidirectional update(len_t pos, const hash_bidirectional &x) const{ return hash_bidirectional(*this).inplace_update(pos, x); }
#define COMPARE_OP(op)\
bool operator op(const hash_bidirectional &x) const{ return data op x.data; }
    COMPARE_OP(==) COMPARE_OP(!=) COMPARE_OP(<) COMPARE_OP(<=) COMPARE_OP(>) COMPARE_OP(>=)
#undef COMPARE_OP
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional &operator*=(T x){
        assert(x >= 0);
        if(x == 0) return *this = {};
        if(x == 1) return *this;
        hash_bidirectional res{};
        for(auto e = x; e; e >>= 1){
            if(e & 1) res += *this;
            *this += *this;
        }
        return *this = res;
    }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    hash_bidirectional operator*(T x) const{ return hash_bidirectional(*this) *= x; }
    template<class T, typename enable_if<is_integral_v<T>>::type* = nullptr>
    friend hash_bidirectional operator*(T x, const hash_bidirectional &h){ return hash_bidirectional(h) *= x; }
    friend ostream &operator<<(ostream &out, const hash_bidirectional &x){ return out << "{" << x.data << ", " << x.rev_data << ", " << x.len << "}"; }
    modular_t data = 0, rev_data = 0;
    len_t len = 0;
#undef ASSERT
};
template<class modular_t, class len_t, bool ALLOW_BINEXP> modular_t hash_bidirectional<modular_t, len_t, ALLOW_BINEXP>::_base;
template<class modular_t, class len_t, bool ALLOW_BINEXP> modular_t hash_bidirectional<modular_t, len_t, ALLOW_BINEXP>::_inv_base;
template<class modular_t, class len_t, bool ALLOW_BINEXP> vector<modular_t> hash_bidirectional<modular_t, len_t, ALLOW_BINEXP>::_power;
template<class modular_t, class len_t, bool ALLOW_BINEXP> vector<modular_t> hash_bidirectional<modular_t, len_t, ALLOW_BINEXP>::_inv_power;

using hash_t = hash_bidirectional<modular_fixed_base<unsigned long long, (unsigned long long)1e18 + 9>, int, false>;

// Requires modular and (hash or hash_bidirectional)
template<class hash_t>
struct substring_hasher{
    int n;
    vector<hash_t> prefix;
    substring_hasher(){ }
    // O(n)
    template<class T>
    substring_hasher(const vector<T> &a){ build(a); }
    // O(n)
    template<class T>
    void build(const vector<T> &a){
        n = (int)a.size();
        prefix.resize(n + 1);
        for(auto i = 0; i < n; ++ i) prefix[i + 1] = prefix[i] + a[i];
    }
    // O(1)
    hash_t hash(int l, int r) const{
        assert(0 <= l && l <= r && r <= n);
        return prefix[r].pop_left(prefix[l]);
    }
};

const int mxN = 1e6 + 5;
modular base[mxN];

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


    auto cook = [&](int n, vector<vector<int>> &g) -> vector<u64> {
        bool find_cycle = false;
        vector<int> par(n, -1), vis(n), vcyc(n), cyc;
        auto dfs_cyc = [&](auto self, int u, int p) -> void {
            vis[u] = true, par[u] = p;
            for (auto v : g[u]) if (v != p) {
                if (find_cycle) return;
                if (vis[v]) {
                    int cur = u;
                    vcyc[u] = true;
                    cyc.emplace_back(u);
                    while (cur != v) {
                        cur = par[cur];
                        vcyc[cur] = true;
                        cyc.emplace_back(cur);
                    }
                    find_cycle = true;
                }
                else {
                    self(self, v, u);
                }
            }
        };
        dfs_cyc(dfs_cyc, 0, -1);

        vector<modular> hash(n);
        auto dfs = [&](auto self, int u) -> int {
            int d = 1;
            hash[u] = 1;
            vcyc[u] = true;
            vector<int> child;
            for (auto v : g[u]) if (not vcyc[v]) {
                child.emplace_back(v);
                d = max(d, self(self, v) + 1);
            }
            for (auto v : child) {
                hash[u] *= base[d] + hash[v];
            }
            return d;
        };
        vector<u64> res;
        for (auto u : cyc) {
            dfs(dfs, u);
            res.emplace_back(hash[u].data);
        }
        // cout << isz(cyc) << endl;
        res.insert(res.end(), all(res));
        return res;
    };

    substring_hasher<hash_t> sh;
    map<pair<int, u64>, int> mp;
    for (int i = 0; i < n; ++i) {
        int cnt;
        cin >> cnt;

        vector<vector<int>> g(cnt);
        for (int i = 0; i < cnt; ++i) {
            int u, v;
            cin >> u >> v;
            --u, --v;
            g[u].emplace_back(v);
            g[v].emplace_back(u);
        }

        auto vec = cook(cnt, g);

        int sz = isz(vec) / 2;

        sh.build(vec);
        bool find = false;
        for (int i = 0; i < sz; ++i) {
            auto val = sh.hash(i, i + sz);
            if (mp.count({cnt, val.data.data})) {
                find = true;
                break;
            }
            if (mp.count({cnt, val.rev_data.data})) {
                find = true;
                break;
            }
        }
        if (not find) {
            mp[{cnt, sh.hash(0, sz).data.data}]++;
        }
    }
    cout << isz(mp) << endl;
}

signed main() {

#ifndef CDuongg
    if (fopen(taskname".inp", "r"))
        assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout));
#else
    freopen("bai3.inp", "r", stdin);
    freopen("bai3.out", "w", stdout);
    auto start = chrono::high_resolution_clock::now();
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    hash_t::setup();
    for (int i = 0; i < mxN; ++i) {
        base[i] = rng();
    }
    int t = 1; cin >> t;
    while(t--) solve();

#ifdef CDuongg
   auto end = chrono::high_resolution_clock::now();
   cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '=';
   cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl;
#endif

}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 6ms
memory: 11412kb

input:

1
2
4 1 2 2 3 3 1 1 4
4 1 2 2 3 3 1 2 4

output:

1

result:

ok single line: '1'

Test #2:

score: 0
Accepted
time: 3ms
memory: 11492kb

input:

2
2
4 1 2 2 3 3 1 1 4
5 1 2 2 3 3 1 2 4 2 5
3
9 1 2 2 5 5 7 7 6 6 3 3 1 2 4 7 9 9 8
9 1 4 4 2 2 3 3 5 5 7 7 6 6 4 7 8 8 9
9 1 2 2 5 5 4 4 1 4 7 7 8 8 6 8 9 5 3

output:

2
2

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 8076ms
memory: 33416kb

input:

30
332526
3 3 2 3 1 2 1
3 2 3 3 1 1 2
3 1 3 1 2 3 2
3 3 2 2 1 1 3
3 2 1 2 3 1 3
3 1 3 1 2 3 2
3 1 2 2 3 3 1
3 2 1 2 3 1 3
3 3 1 3 2 1 2
3 1 3 1 2 3 2
3 1 3 3 2 2 1
3 1 2 2 3 3 1
3 3 1 3 2 1 2
3 2 1 2 3 1 3
3 3 2 2 1 1 3
3 1 2 1 3 2 3
3 1 2 1 3 2 3
3 2 3 2 1 3 1
3 1 2 1 3 2 3
3 3 1 1 2 2 3
3 1 3 1 2 ...

output:

1
4
5
89
93
242
628
1575
3401
5703
7718
8888
9258
9355
9356
9203
9211
89
239
648
1739
4541
10352
19037
27089
31567
33030
33068
32480
31503

result:

ok 30 lines

Test #4:

score: 0
Accepted
time: 8036ms
memory: 14928kb

input:

30
333333
3 2 1 2 3 3 1
3 1 2 3 2 3 1
3 3 2 1 3 1 2
3 2 3 2 1 3 1
3 2 3 2 1 1 3
3 1 2 3 2 3 1
3 3 1 2 1 3 2
3 1 3 1 2 3 2
3 1 3 2 3 1 2
3 2 1 3 2 3 1
3 2 3 1 2 1 3
3 3 1 1 2 3 2
3 3 2 3 1 1 2
3 2 1 3 1 3 2
3 3 2 1 2 3 1
3 3 2 1 2 1 3
3 2 3 2 1 1 3
3 1 2 3 2 3 1
3 3 1 1 2 3 2
3 1 3 1 2 2 3
3 1 2 3 2 ...

output:

1
2
5
13
33
89
240
653
1771
4753
11868
24982
40524
51128
54690
54119
52143
49848
47551
45441
43471
41664
40000
38461
37037
35714
34482
33333
32258
31250

result:

ok 30 lines

Test #5:

score: 0
Accepted
time: 21421ms
memory: 161728kb

input:

30
2
500000 12446 494050 179161 216388 282442 232792 428247 130742 87062 493860 276791 469755 342468 58973 93535 429405 5662 112197 121541 62083 28611 427877 376918 349780 372239 58010 457751 308686 448844 473714 151350 480692 152372 415617 311966 298916 302690 200753 75481 396263 318635 79619 39930...

output:

1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2

result:

ok 30 lines

Test #6:

score: 0
Accepted
time: 206ms
memory: 77780kb

input:

1
4
240000 1 2 2 3 3 4 4 7 1 5 2 6 7 8 8 9 9 10 10 13 7 11 8 12 13 14 14 15 15 16 16 19 13 17 14 18 19 20 20 21 21 22 22 25 19 23 20 24 25 26 26 27 27 28 28 31 25 29 26 30 31 32 32 33 33 34 34 37 31 35 32 36 37 38 38 39 39 40 40 43 37 41 38 42 43 44 44 45 45 46 46 49 43 47 44 48 49 50 50 51 51 52 52...

output:

2

result:

ok single line: '2'