제출 #1221742

#제출 시각아이디문제언어결과실행 시간메모리
1221742The_Samurai조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++20
100 / 100
463 ms65476 KiB
// I stand with PALESTINE //#pragma GCC optimize("Ofast") //#pragma GCC optimize ("unroll-loops") //#pragma GCC target("avx,avx2") #include <bits/stdc++.h> //#include <ext/pb_ds/assoc_container.hpp> using namespace std; //using namespace __gnu_pbds; // #define int long long #define ff first #define ss second #define sz(a) (int) (a).size() //template<class T, class C = null_type> using ordered_tree = tree<T, C, less<T>, rb_tree_tag, tree_order_statistics_node_update>; typedef long double ld; namespace io { template<typename F, typename S> ostream &operator<<(ostream &os, const pair<F, S> &p) { return os << p.ff << " " << p.ss; } template<typename F, typename S> ostream &operator<<(ostream &os, const map<F, S> &mp) { for (auto it: mp) { os << it << endl; } return os; } template<typename F> ostream &operator<<(ostream &os, const vector<F> &v) { bool space = false; for (F x: v) { if (space) os << " "; space = true; os << x; } return os; } template<typename F> ostream &operator<<(ostream &os, const deque<F> &d) { bool space = false; for (F x: d) { if (space) os << " "; space = true; os << x; } return os; } template<typename F> ostream &operator<<(ostream &os, const set<F> &st) { bool space = false; for (F x: st) { if (space) os << " "; space = true; os << x; } return os; } template<typename F> ostream &operator<<(ostream &os, const multiset<F> &st) { bool space = false; for (F x: st) { if (space) os << " "; space = true; os << x << x; } return os; } template<typename F, typename S> istream &operator>>(istream &is, pair<F, S> &p) { return is >> p.ff >> p.ss; } template<typename F> istream &operator>>(istream &is, vector<F> &v) { for (F &x: v) { is >> x; } return is; } long long fastread() { char c; long long d = 1, x = 0; do c = getchar(); while (c == ' ' || c == '\n'); if (c == '-') c = getchar(), d = -1; while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return d * x; } static bool sep = false; using std::to_string; string to_string(bool x) { return (x ? "true" : "false"); } string to_string(const string &s) { return "\"" + s + "\""; } string to_string(const char *s) { return "\"" + string(s) + "\""; } string to_string(const char &c) { string s; s += c; return "\'" + s + "\'"; } template<typename Type> string to_string(vector<Type>); template<typename F, typename S> string to_string(pair<F, S>); template<typename Collection> string to_string(Collection); template<typename F, typename S> string to_string(pair<F, S> p) { return "{" + to_string(p.ff) + ", " + to_string(p.ss) + "}"; } template<typename Type> string to_string(vector<Type> v) { bool sep = false; string s = "["; for (Type x: v) { if (sep) s += ", "; sep = true; s += to_string(x); } s += "]"; return s; } template<typename Collection> string to_string(Collection collection) { bool sep = false; string s = "{"; for (auto x: collection) { if (sep) s += ", "; sep = true; s += to_string(x); } s += "}"; return s; } void print() { cout << endl; sep = false; } template<typename F, typename... Other> void print(F ff, Other... other) { if (sep) cout << " | "; sep = true; cout << to_string(ff); print(other...); } } using namespace io; namespace utils { template<typename F, typename S> inline void maxs(F &a, S b) { a = a > b ? a : b; } template<typename F, typename S> inline void mins(F &a, S b) { a = a < b ? a : b; } template<typename F, typename S> long long max(F a, S b) { return a > b ? a : b; } template<typename F, typename S> long long min(F a, S b) { return a < b ? a : b; } constexpr long long operator "" _E(unsigned long long n) { long long p = 1, a = 10; for (int i = 0; i < n; i++) p *= a; return p; } random_device rd; mt19937 mt(rd()); template<typename T> T rand(T l, T r) { uniform_int_distribution<T> dist(l, r); return dist(mt); }; } using namespace utils; #ifdef sunnatov #define print(...) cout << "[" << #__VA_ARGS__ << "]: "; io::print( __VA_ARGS__ ); #else #define print( ... ) 42 #endif const int mod = 9_E + 7; const double EPS = 1e-7; long long doxuya = 18_E + 10; int INF = 9_E + 10; const char nl = '\n'; int month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* */ using ll = long long; void solution(istream &cin, ostream &cout, const int &test_case) { int n, m; cin >> n >> m; // vector con(n + 1, vector(n + 1, false)); // auto brute = [&](int u, int v) -> int { // con[u][v] = true; // for (int t = 0; t < n; t++) { // for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) { // if (i == j or i == k or j == k) continue; // if (con[i][j] and con[j][k] and con[k][j]) con[i][k] = true; // } // } // int ans = 0; // for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) ans += con[i][j]; // return ans; // }; vector<vector<int>> have(n + 1); vector<set<pair<int, int>>> in(n + 1); vector<set<int>> out(n + 1), all_out(n + 1); vector<int> par(n + 1); vector<ll> size(n + 1, 1); ll ans = 0; for (int i = 1; i <= n; i++) par[i] = i; for (int i = 1; i <= n; i++) have[i].emplace_back(i); auto check = [&](set<pair<int, int>> &st, int u) -> bool { auto it = st.lower_bound(make_pair(u, 0)); return it != st.end() and it->first == u; }; queue<pair<int, int>> q; auto merge = [&](int u, int v) -> void { u = par[u]; v = par[v]; if (size[u] + sz(in[u]) + sz(all_out[u]) < size[v] + sz(in[v]) + sz(all_out[v])) swap(u, v); ans -= size[u] * (size[u] - 1); ans -= size[v] * (size[v] - 1); ans -= sz(in[u]) * size[u]; ans -= sz(in[v]) * size[v]; size[u] += size[v]; for (int x: have[v]) { have[u].emplace_back(x); par[x] = u; for (int y: out[x]) { in[y].erase(make_pair(v, x)); if (y == u) continue; in[y].emplace(u, x); all_out[u].insert(y); if (check(in[u], y)) q.emplace(u, y); } } for (auto [x, y]: in[v]) { if (x == u) { out[y].erase(v); if (all_out[x].count(v)) all_out[x].erase(v); continue; } out[y].erase(v); out[y].insert(u); if (all_out[x].count(v)) all_out[x].erase(v); all_out[x].insert(u); in[u].emplace(x, y); if (all_out[u].count(x)) q.emplace(u, x); } have[v].clear(); in[v].clear(); all_out[v].clear(); ans += size[u] * (size[u] - 1); ans += sz(in[u]) * size[u]; }; while (m--) { int u, v; cin >> u >> v; if (par[u] == par[v]) { // assert(ans == brute(u, v)); cout << ans << nl; continue; } if (!check(in[par[u]], par[v])) { if (!out[u].count(par[v])) { out[u].insert(par[v]); all_out[par[u]].insert(par[v]); in[par[v]].emplace(par[u], u); ans += size[par[v]]; } // assert(ans == brute(u, v)); cout << ans << nl; continue; } q.emplace(u, v); while (!q.empty()) { auto [u, v] = q.front(); q.pop(); if (par[u] != par[v]) merge(u, v); } // print(ans); // print(brute(u, v)); // assert(ans == brute(u, v)); cout << ans << nl; } } int32_t main() { clock_t startTime = clock(); cin.tie(0)->sync_with_stdio(false); srand(time(0)); std::istream &in(std::cin); std::ostream &out(std::cout); int32_t queries = 1; #ifdef test_cases freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); cin >> queries; #else // cin >> queries; #endif for (int32_t test_case = 1; test_case <= queries; test_case++) { print(test_case); solution(cin, cout, test_case); cout << nl; } #ifdef sunnatov cout << "Time: " << (int) ((double) (clock() - startTime) / CLOCKS_PER_SEC * 1000) << " ms" << endl; #endif return EXIT_SUCCESS; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...