Submission #646239

#TimeUsernameProblemLanguageResultExecution timeMemory
646239Matteo_VerzColors (RMI18_colors)C++17
100 / 100
615 ms87576 KiB
/*
                `-/oo+/-   ``
              .oyhhhhhhyo.`od
             +hhhhyyoooos. h/
            +hhyso++oosy- /s
           .yoooossyyo:``-y`
            ..----.` ``.-/+:.`
                   `````..-::/.
                  `..```.-::///`
                 `-.....--::::/:
                `.......--::////:
               `...`....---:::://:
             `......``..--:::::///:`
            `---.......--:::::////+/`
            ----------::::::/::///++:
            ----:---:::::///////////:`
            .----::::::////////////:-`
            `----::::::::::/::::::::-
             `.-----:::::::::::::::-
               ...----:::::::::/:-`
                 `.---::/+osss+:`
                   ``.:://///-.
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <cmath>
#define debug(x) cerr << #x << " " << x << '\n'
#define debugsp(x) cerr << #x << " " << x << ' '
 
using namespace std;
 
const int INF = 2e9;
const int N = 150000;
const int M = 250000;
 
struct Edge {
  int from, to;
};
 
Edge ve[1 + M];
int a[1 + N], b[1 + N];
vector <int> cola[1 + N], colb[1 + N];
 
class DSU {
  private:
    struct DSUedge {
      int node;
      int from, to;
      int size_from, size_to;
 
      DSUedge() {
        node = from = to = size_from = size_to = 0;
      }
 
      DSUedge(int nod, int x, int y, int szx, int szy) {
        node = nod;
        from = x; to = y;
        size_from = szx; size_to = szy;
      }
    };
 
    vector <int> rank;
    vector <int> parent;
    vector <bool> goodComponent;
    stack <DSUedge> st;
    
    public:
      void Init(int n) {
        while(st.size()) st.pop();
        rank.resize(1 + n);
        parent.resize(1 + n);
        goodComponent.resize(1 + n);
        
        for(int i = 1; i <= n; i++) {
          rank[i] = 1;
          parent[i] = i;
          goodComponent[i] = false;
        }
      }
 
      int Find(int x) {
        if(parent[x] == x) return x;
        return Find(parent[x]);
      }
 
      void Unite(int node, int x, int y) {
        x = Find(x);
        y = Find(y);
 
        if(x == y) return;
        
        if(rank[x] < rank[y]) swap(x, y);
        DSUedge e = {node, x, y, rank[x], rank[y]};
        
        st.push(e);
        parent[y] = x;
        rank[x] += rank[y];
        rank[y] = rank[x];
      }
 
      void RollBack(int node) {
        while(st.size() && st.top().node == node) {
          DSUedge e = st.top();
          st.pop();
 
          rank[e.from] = e.size_from; rank[e.to] = e.size_to;
          parent[e.from] = e.from; parent[e.to] = e.to;
        }
      }
 
      void ChangeValue(int node, bool value) {
        node = Find(node);
        goodComponent[node] = value;
      }
 
      bool IsGood(int node) {
        node = Find(node);
        return goodComponent[node];
      }
};
 
class Segment_Tree {
  private:
    vector <vector <Edge>> ev;
    DSU dsu;
 
  public:
    void Init(int n, int m) {
      ev.resize(1 + 4 * n);
      for(int i = 0; i < ev.size(); i++)
        ev[i].clear();
      dsu.Init(n);
    }
 
    void Update(int node, int l, int r, int x, int y, Edge e) {
      if(x <= l && r <= y)
        ev[node].push_back(e);
      else {
        int mid = (l + r) >> 1;
 
        if(x <= mid) Update(node << 1, l, mid, x, y, e);
        if(y > mid) Update(node << 1 | 1, mid + 1, r, x, y, e);
      }
    }
 
    bool DFS(int node, int l, int r) {
      bool ok(true);
      for(Edge e : ev[node]) {
        dsu.Unite(node, e.from, e.to);
      }
 
      if(l == r) {
        for(int fromnode : cola[l]) 
          dsu.ChangeValue(fromnode, true);
        
        for(int tonode : colb[l]) 
          if(!dsu.IsGood(tonode))
            ok = false;
 
        for(int fromnode : cola[l])
          dsu.ChangeValue(fromnode, false);
      } else {
        int mid = (l + r) >> 1;
        ok &= (DFS(node << 1, l, mid) & DFS(node << 1 | 1, mid + 1, r));
      }
 
      dsu.RollBack(node);
      return ok;
    }
};
Segment_Tree aint;
 
int n, m;
bool Solve_Test() {
  bool ok(true);
  scanf("%d%d", &n, &m);
 
  for(int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    cola[a[i]].push_back(i);
  }
 
  for(int i = 1; i <= n; i++) {
    scanf("%d", &b[i]); 
    colb[b[i]].push_back(i);
 
    if(b[i] > a[i]) ok = false;
  }
 
  for(int i = 1; i <= m; i++) 
    scanf("%d%d", &ve[i].from, &ve[i].to);
  
  if(ok == false) return false;
  
  aint.Init(n, m);
  for(int i = 1; i <= m; i++)
    aint.Update(1, 1, n, max(b[ve[i].from], b[ve[i].to]), min(a[ve[i].from], a[ve[i].to]), ve[i]);
  return aint.DFS(1, 1, n);
}
 
void Clear() { 
  for(int i = 0; i <= n; i++) {
    a[i] = b[i] = 0;
    cola[i].clear(); colb[i].clear();
  }
 
  for(int i = 0; i <= m; i++)
    ve[i] = Edge{0, 0};
}
 
int main() {
  int t;
  cin >> t;
  
  for(int i = 1; i <= t; i++) {
    cout << Solve_Test() << '\n'; 
    Clear();
  }
  return 0;
}

Compilation message (stderr)

colors.cpp: In member function 'void Segment_Tree::Init(int, int)':
colors.cpp:138:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<Edge> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  138 |       for(int i = 0; i < ev.size(); i++)
      |                      ~~^~~~~~~~~~~
colors.cpp: In function 'bool Solve_Test()':
colors.cpp:184:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  184 |   scanf("%d%d", &n, &m);
      |   ~~~~~^~~~~~~~~~~~~~~~
colors.cpp:187:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  187 |     scanf("%d", &a[i]);
      |     ~~~~~^~~~~~~~~~~~~
colors.cpp:192:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  192 |     scanf("%d", &b[i]);
      |     ~~~~~^~~~~~~~~~~~~
colors.cpp:199:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  199 |     scanf("%d%d", &ve[i].from, &ve[i].to);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...