Submission #1146093

#TimeUsernameProblemLanguageResultExecution timeMemory
1146093Mike_VuColors (RMI18_colors)C++17
22 / 100
149 ms25416 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef double dou; #define pii pair<int, int> #define fi first #define se second #define pb push_back #define BITJ(x, j) (((x)>>(j))&1) #define MASK(j) (1LL<<(j)) #define ALL(v) v.begin(), v.end() template<typename T> bool maximize(T &x, const T &y) { if (x < y) {x = y; return 1;} return 0; } template<typename T> bool minimize(T &x, const T &y) { if (x > y) {x = y; return 1;} return 0; } struct BIT{ int n; vector<int> bit; void init(int _n = 0) { n = _n; bit.assign(n+1, 0); } void update(int k, int x){ while (k <= n) { bit[k] += x; k += k & (-k); } } int getsum(int k) { int res = 0; while (k > 0) { res += bit[k]; k -= k & (-k); } return res; } int query(int l, int r) { return getsum(r)-getsum(l-1); } }; const int maxn = 15e4+5, lg = 18; int n, m, a[maxn], b[maxn]; vector<int> adj[maxn], posa[maxn], posb[maxn]; bool ans; bool act[maxn]; void input() { cin >> n >> m; for (int i = 1; i <= n; i++) { adj[i].clear(); posa[i].clear(); posb[i].clear(); } for (int i= 1; i <= n; i++) { cin >> a[i]; posa[a[i]].pb(i); } for (int i = 1; i <= n; i++) { cin >> b[i]; posb[b[i]].pb(i); } for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; adj[u].pb(v); adj[v].pb(u); } } namespace trau{ struct DSU{ int n; vector<int> dsu; vector<bool> val; void init(int _n) { n = _n; dsu.assign(n+1, -1); val.assign(n+1, 0); } int f(int u) { return dsu[u] < 0 ? u : dsu[u] = f(dsu[u]); } bool join(int u, int v) { u = f(u); v = f(v); if (u == v) return 0; if (dsu[u] > dsu[v]) swap(u, v); dsu[u] += dsu[v]; dsu[v] = u; val[u] = val[u]|val[v]; return 1; } void turn(int u, bool x) { val[f(u)] = x; } bool fval(int u) { return val[f(u)]; } }; DSU dsu; void addnode(int u) { act[u] = 1; for (int v : adj[u]) { if (act[v]) { dsu.join(u, v); } } } void solve() { //clear for (int i = 1; i <= n; i++) { act[i] = 0; } //dsu 1 dsu.init(n); for (int i = n; i; i--) { if (posa[i].empty() && !posb[i].empty()) { ans = 0; return; } for (int u : posa[i]) { addnode(u); } for (int u : posa[i]) { dsu.turn(u, 1); } for (int u : posb[i]) { if (!act[u] || !dsu.fval(u)) { ans = 0; return; } } for (int u : posa[i]) { dsu.turn(u, 0); } } //dsu 2 dsu.init(n); for (int i= 1; i <= n; i++) { act[i] = 0; } for (int i = 1; i <= n; i++) { for (int u : posb[i]) { addnode(u); } for (int u : posa[i]) { dsu.turn(u, 1); } for (int u : posb[i]) { if (!dsu.fval(u)) { ans = 0; return; } } for (int u : posa[i]) { dsu.turn(u, 0); } } } } namespace full{ int lab[maxn]; vector<int> tradja[maxn], tradjb[maxn], qu[maxn], nadj[maxn]; BIT bit; int cornodeb[maxn], cornodea[maxn];//save the corresponding ancestor for each b int par[maxn][lg], h[maxn]; int tinb[maxn], toutb[maxn], timer, tina[maxn], touta[maxn], sz[maxn], heavy[maxn], nodeti[maxn]; bool vis[maxn]; namespace dsutree{ void init() { for (int i = 1; i <= n; i++) { lab[i] = -1; act[i] = 0; } } int f(int u) { return lab[u] < 0 ? u : lab[u] = f(lab[u]); } void addnode(int u, vector<int> tradj[]) { act[u] = 1; for (int v : adj[u]) { if (act[v]) { int nv = f(v); if (u == nv) continue; lab[nv] = u; tradj[u].pb(nv); } } } } void dfsp1(int u) { act[u] = 1; for (int j = 1; j < lg; j++) { if (MASK(j) >= h[u]) break; par[u][j] = par[par[u][j-1]][j-1]; } tina[u] = ++timer; nodeti[timer] = u; // cout << u << ' ' << h[u] << ' ' << par[u][0] << endl; for (int v : tradja[u]) { if (act[v]) continue; // cout << "edge 1 " << u << ' ' << v << "\n"; h[v] = h[u]+1; par[v][0] = u; dfsp1(v); } touta[u] = timer; } void dfsp2(int u) { // cout << u << endl; act[u] = 1; tinb[u] = ++timer; for (int v : tradjb[u]) { if (act[v]) continue; // cout << "edge 2 " << u << ' ' << v << "\n"; dfsp2(v); } toutb[u] = timer; } int lca(int u, int v) { if (h[u] < h[v]) swap(u, v); if (h[u] != h[v]) { int k = h[u]-h[v]; for (int j = 0; j < lg; j++) { if (BITJ(k, j)) { u = par[u][j]; } } } if (u == v) return u; for (int j = lg-1; j >= 0; j--) { while (h[u] > MASK(j) && par[u][j] != par[v][j]){ u = par[u][j]; v = par[v][j]; } } return par[u][0]; } bool cmpnode(int u, int v) { return tina[u] < tina[v]; } void swit(int u, int x) { // cout << u << ' ' << tinb[u] << ' ' << x << "\n"; bit.update(tinb[u], x); } void dfsprep(int u) { vis[u] = 1; sz[u] = 1; heavy[u] = -1; for (int v : nadj[u]) { dfsprep(v); sz[u] += sz[v]; if (heavy[u] == -1 || sz[v] > sz[heavy[u]]) { heavy[u] = v; } } } void dfssolve(int u, bool del) { vis[u] = 1; //light for (int v : nadj[u]) { if (v == heavy[u]) continue; dfssolve(v, 1); } //heavy if (heavy[u] != -1) dfssolve(heavy[u], 0); //light for (int v : nadj[u]) { if (v == heavy[u]) continue; for (int i = tina[v]; i <= touta[v]; i++) { if (act[nodeti[i]]) swit(nodeti[i], 1); } } //u if (act[u]) swit(u, 1); //solve query for (int v : qu[u]) { // cout << "query " << v << ' ' << tinb[v] << ' ' << toutb[v] << ' ' << bit.query(tinb[v], toutb[v]) << "\n"; if (bit.query(tinb[v], toutb[v]) == 0) { ans &= 0; } } //del if (del) { for (int i = tina[u]; i <= touta[u]; i++) { if (act[nodeti[i]]) swit(nodeti[i], -1); } } } void virsolve(vector<int> &nodea, vector<int> &nodeb){ vector<int> nodes; //build nodes for (int u : nodea) { nodes.pb(u); act[u] = 1; } for (int u : nodeb) { nodes.pb(u); qu[cornodea[u]].pb(cornodeb[u]); } sort(ALL(nodes), cmpnode); int k = (int)nodes.size(); for (int i =1; i < k; i++) { // cout << nodes[i] << ' ' << nodes[i-1] << ' ' << lca(nodes[i], nodes[i-1]) << endl; nodes.pb(lca(nodes[i], nodes[i-1])); } // system("pause"); sort(ALL(nodes), cmpnode); nodes.erase(unique(ALL(nodes)), nodes.end()); //build edges vector<int> stk; stk.pb(nodes[0]); k = nodes.size(); for (int i = 1; i < k; i++) { int p = stk.back(), u = nodes[i]; while (tina[p] > tina[u] || touta[p] < touta[u]) { stk.pop_back(); p = stk.back(); } // cout << p << ' ' << u << "\n"; nadj[p].pb(u); } // system("pause"); //sack on tree + solve for (int u : nodes) { if (!vis[u]) { dfsprep(u); } } for (int u : nodes) { vis[u] = 0; } // system("pause"); for (int u : nodes) { if (!vis[u]) { dfssolve(u, 1); } } // system("pause"); //reset for (int u : nodes) { nadj[u].clear(); qu[u].clear(); act[u] = vis[u] = 0; } } void solve() { //clear for (int i = 1; i <= n ;i++) { tradjb[i].clear(); tradja[i].clear(); qu[i].clear(); } ///check special case //tree b dsutree::init(); //add for (int i = 1; i <= n; i++) { if (posa[i].empty() && !posb[i].empty()) { ans = 0; return; } for (int u : posb[i]) { dsutree::addnode(u, tradjb); } for (int u : posb[i]) { if (b[u] > a[u]) {//must be in the active nodes ans = 0; // cout << "i am here :D\n"; return; } int nu = dsutree::f(u); cornodeb[u] = nu; } } //take root -> vector //prep euler tour tree b for (int i = 1; i <= n; i++) { act[i] = 0; } timer = 0; for (int i = 1; i <= n; i++) { int u = dsutree::f(i); if (!act[u]) { dfsp2(u); } } //tree a dsutree::init(); //add for (int i= n; i; i--) { for (int u : posa[i]) { dsutree::addnode(u, tradja); } for (int u : posb[i]) { int nu = dsutree::f(u); cornodea[u] = nu; } } //take root -> array //prep lca tree a for (int i = 1; i <= n; i++) { act[i] = 0; } timer = 0; for (int i = 1; i <= n; i++) { //reset state int u = dsutree::f(i); if (!act[u]) { h[u] = 1; dfsp1(u); } } //reset state for (int i = 1; i <= n; i++) { act[i] = 0; } bit.init(n); //virtual tree for each lvl for (int i = n; i; i--) { if (posb[i].empty()) continue; // cout << i << endl; // system("pause"); virsolve(posa[i], posb[i]); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); // #define name "task" // if (fopen(name".inp", "r")) { // freopen(name".inp", "r", stdin); // freopen(name".out", "w", stdout); // } int t; cin >> t; // while (cin >> n >> m) { while (t--) { input(); ans = 1; // trau::solve(); full::solve(); cout << ans << "\n"; // cout << endl; } } /* 1 7 9 1 2 3 1 2 2 1 1 2 3 1 2 2 1 4 7 1 6 3 7 5 7 1 5 3 4 1 4 1 3 2 7 1 4 4 3 3 2 1 1 2 2 1 1 2 2 3 3 4 4 2 2 4 4 3 3 2 1 2 1 2 1 1 2 2 3 3 4 4 2 4 4 3 3 2 1 1 2 2 1 1 2 2 3 3 4 4 2 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...