제출 #1351564

#제출 시각아이디문제언어결과실행 시간메모리
1351564SmuggingSpunJail (JOI22_jail)C++20
100 / 100
454 ms22752 KiB
#include<bits/stdc++.h>
#define taskname "A"
using namespace std;
typedef long long ll;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
template<class T>void maximize(T& a, T b){
  if(a < b){
    a = b;
  }
}
const int lim = 12e4 + 5;
int n, m, s[lim], t[lim];
vector<int>g[lim];
namespace sub1{
  void solve(){
    function<bool(void)>work = [&] (){
      vector<ll>f(n + 2, 0);
      vector<int>right(n + 1, -1);
      for(int i = 1; i <= m; i++){
        if(s[i] < t[i]){
          f[s[i]]++;
          f[(right[s[i]] = t[i]) + 1]--;
        }
      }
      for(int _ = 0; _ < 2; _++){
        for(int i = 1; i <= n; i++){
          f[i] += f[i - 1];
        }
      }
      for(int i = 1; i <= m; i++){
        if(t[i] < s[i] && f[s[i]] > f[t[i] - 1]){
          return false;
        }
      }
      for(int i = n, mir = n + 1; i > 0; i--){
        if(right[i] != -1){
          if(right[i] > mir){
            return false;
          }
          minimize(mir, right[i]);
        }
      }
      return true;
    };
    if(!work()){
      return void(cout << "No\n");
    }
    for(int i = 1; i <= m; i++){
      s[i] = n - s[i] + 1;
      t[i] = n - t[i] + 1;
    }
    cout << (work() ? "Yes\n" : "No\n");
  }
}
namespace sub2{
  const int lim = 251;
  vector<int>path[2];
  void solve(){
    for(int i = 1; i <= m; i++){
      queue<int>q;
      q.push(s[i]);
      vector<int>par(n + 1, -1);
      par[s[i]] = 0;
      while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int& v : g[u]){
          if(par[v] == -1){
            par[v] = u;
            q.push(v);
          }
        }
      }
      path[i - 1].clear();
      for(int j = t[i]; j != s[i]; j = par[j]){
        path[i - 1].push_back(j);
      }
      path[i - 1].push_back(s[i]);
      reverse(path[i - 1].begin(), path[i - 1].end());
    }
    vector<bool>f(path[1].size(), false);
    f[0] = true;
    for(int j = 1; j < path[1].size(); j++){
      f[j] = f[j - 1] && path[0][0] != path[1][j];
    }
    for(int i = 1; i < path[0].size(); i++){
      vector<bool>nf(path[1].size(), false);
      for(int j = 0; j < path[1].size(); j++){
        nf[j] = path[0][i] != path[1][j] && ((j > 0 && nf[j - 1]) || f[j]);
      }
      swap(f, nf);
    }
    cout << (f.back() ? "Yes\n" : "No\n");
  }
}
namespace sub3{
  const int lim = 251;
  void solve(){
    vector<bitset<lim>>vis(m + 1);
    for(int i = 1; i <= m; i++){
      queue<int>q;
      q.push(s[i]);
      vector<int>par(n + 1, -1);
      par[s[i]] = 0;
      while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int& v : g[u]){
          if(par[v] == -1){
            par[v] = u;
            q.push(v);
          }
        }
      }
      vis[i].reset();
      for(int j = t[i]; j != s[i]; j = par[j]){
        vis[i][j] = true;
      }
      vis[i][s[i]] = true;
    }
    vector<int>p(m);
    iota(p.begin(), p.end(), 1);
    do{
      bool flag = true;
      for(int i = 0; i < m; i++){
        for(int j = 0; j < i; j++){
          if(vis[p[i]][t[p[j]]]){
            flag = false;
            break;
          }
        }
        if(!flag){
          break;
        }
        for(int j = i + 1; j < m; j++){
          if(vis[p[i]][s[p[j]]]){
            flag = false;
            break;
          }
        }
        if(!flag){
          break;
        }
      }
      if(flag){
        return void(cout << "Yes\n");
      }
    } while(next_permutation(p.begin(), p.end()));
    cout << "No\n";
  }
}
namespace sub4{
  void solve(){
    vector<bitset<lim>>vis(m + 1);
    for(int i = 1; i <= m; i++){
      queue<int>q;
      q.push(s[i]);
      vector<int>par(n + 1, -1);
      par[s[i]] = 0;
      while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int& v : g[u]){
          if(par[v] == -1){
            par[v] = u;
            q.push(v);
          }
        }
      }
      vis[i].reset();
      for(int j = t[i]; j != s[i]; j = par[j]){
        vis[i][j] = true;
      }
      vis[i][s[i]] = true;
    }
    vector<int>in(m + 1, 0);
    for(int i = 1; i <= m; i++){
      g[i].clear();
      for(int j = 1; j <= m; j++){
        if(i != j && (vis[i][t[j]] || vis[j][s[i]])){
          g[i].push_back(j);
          in[j]++;
        }
      }
    }
    queue<int>q;
    for(int i = 1; i <= m; i++){
      if(in[i] == 0){
        q.push(i);
      }
    }    
    for(int _ = 0; _ < m; _++){
      if(q.empty()){
        return void(cout << "No\n");
      }
      int u = q.front();
      q.pop();
      for(int& v : g[u]){
        if(--in[v] == 0){
          q.push(v);
        }
      }
    }
    cout << "Yes\n";
  }
}
namespace sub5{
  void solve(){
    vector<int>siz(n + 1), low(n + 1), h(n + 1), par(n + 1), head(n + 1);
    function<void(int)>dfs, hld;
    dfs = [&] (int s){
      siz[s] = 1;
      for(int& d : g[s]){
        if(d != par[s]){
          h[d] = h[par[d] = s] + 1;
          dfs(d);
          siz[s] += siz[d];
        }
      }
    };
    int thld = h[1] = par[1] = 0;
    dfs(1);
    hld = [&] (int s){
      low[s] = ++thld;
      int heavy = -1;
      for(int& d : g[s]){
        if(d != par[s] && (heavy == -1 || siz[heavy] < siz[d])){
          heavy = d;
        }
      }
      if(heavy != -1){
        head[heavy] = head[s];
        hld(heavy);
        for(int& d : g[s]){
          if(d != par[s] && d != heavy){
            hld(head[d] = d);
          }
        }
      }
    };
    hld(head[1] = 1);
    function<bool(int, int, int)>inside = [&] (int u, int v, int p){
      while(head[u] != head[v]){
        if(h[head[u]] < h[head[v]]){
          swap(u, v);
        }
        if(low[head[u]] <= low[p] && low[u] >= low[p]){
          return true;
        }
        u = par[head[u]];
      }
      if(low[u] > low[v]){
        swap(u, v);
      }
      return low[u] <= low[p] && low[v] >= low[p];
    };
    vector<int>in(m + 1, 0);
    for(int i = 1; i <= m; i++){
      g[i].clear();
      for(int j = 1; j <= m; j++){
        if(i != j && (inside(s[i], t[i], t[j]) || inside(s[j], t[j], s[i]))){
          g[i].push_back(j);
          in[j]++;
        }
      }
    }
    queue<int>q;
    for(int i = 1; i <= m; i++){
      if(in[i] == 0){
        q.push(i);
      }
    }    
    for(int _ = 0; _ < m; _++){
      if(q.empty()){
        return void(cout << "No\n");
      }
      int u = q.front();
      q.pop();
      for(int& v : g[u]){
        if(--in[v] == 0){
          q.push(v);
        }
      }
    }
    cout << "Yes\n";
  }
}
namespace sub67{
  const int INF = 1e9;
  int thld, snear[lim], h[lim], par[lim], low[lim], tail[lim], low2v[lim], head[lim], siz[lim], lab[lim], t2idm[lim], st[lim << 2], lazy[lim << 2];
  vector<int>lab_st[lim];
  queue<int>topo;
  bitset<lim>in_topo, active;
  int find_set(int i){
    while(i != lab[i]){
      i = lab[i] = lab[lab[i]];
    }
    return i;
  }
  void merge(int i, int j){
    if((i = find_set(i)) != (j = find_set(j))){
      if(lab_st[i].size() < lab_st[j].size()){
        swap(i, j);
      }
      lab[j] = i;
      for(int& id : lab_st[j]){
        if(!in_topo[id]){
          if(find_set(snear[id]) == find_set(t[id])){
            topo.push(id);
            in_topo[id] = true;
          }
          else{
            lab_st[i].push_back(id);
          }
        }
      }
    }
  }
  void dfs(int s){
    siz[s] = 1;
    for(int& d : g[s]){
      if(d != par[s]){
        h[d] = h[par[d] = s] + 1;
        dfs(d);
        siz[s] += siz[d];
      }
    }
  }
  void hld(int s){
    low2v[low[s] = ++thld] = s;
    int heavy = -1;
    for(int& d : g[s]){
      if(d != par[s] && (heavy == -1 || siz[heavy] < siz[d])){
        heavy = d;
      }
    }
    if(heavy != -1){
      head[heavy] = head[s];
      hld(heavy);
      for(int& d : g[s]){
        if(d != par[s] && d != heavy){
          hld(head[d] = d);
        }
      }
    }
    tail[s] = thld;
  }
  void propagate(int id, int x){
    st[id] += x;
    lazy[id] += x;
  }
  void push_down(int id){
    propagate(id << 1, lazy[id]);
    propagate(id << 1 | 1, lazy[id]);
    lazy[id] = 0; 
  }
  void update(int id, int l, int r, int u, int v, int x){
    if(l > v || r < u){
      return;
    }
    if(u <= l && v >= r){
      propagate(id, x);
      return;
    }
    int m = (l + r) >> 1;
    push_down(id);
    update(id << 1, l, m, u, v, x);
    update(id << 1 | 1, m + 1, r, u, v, x);
    st[id] = min(st[id << 1], st[id << 1 | 1]);
  }
  void work(int u){
    active[u] = true;
    for(int& v : g[u]){
      if(active[v]){
        merge(u, v);
      }
    }
  }
  void refine(int id, int l, int r){
    if(st[id] > 1){
      return;
    }
    if(l == r){
      st[id] = INF;
      int i = t2idm[low2v[l]];
      if(i != 0){
        if(active[snear[i]] && active[t[i]] && find_set(snear[i]) == find_set(t[i])){
          topo.push(i);
          in_topo[i] = true;
        }
        else{
          lab_st[find_set(snear[i])].push_back(i);
          lab_st[find_set(t[i])].push_back(i);
        }
      }
      return;
    }
    int m = (l + r) >> 1;
    push_down(id);
    refine(id << 1, l, m);
    refine(id << 1 | 1, m + 1, r);
    st[id] = min(st[id << 1], st[id << 1 | 1]);
  }
  void update_path(int u, int v, int x){
    while(head[u] != head[v]){
      if(h[head[u]] < h[head[v]]){
        swap(u, v);
      }
      update(1, 1, n, low[head[u]], low[u], x);
      u = par[head[u]];
    }
    if(low[u] > low[v]){
      swap(u, v);
    }
    update(1, 1, n, low[u], low[v], x);
  }
  void solve(){
    fill(t2idm + 1, t2idm + n + 1, thld = par[1] = h[1] = 0);
    dfs(1);
    hld(head[1] = 1);
    fill(st, st + (n << 2) + 1, 0);
    fill(lazy, lazy + (n << 2) + 1, 0);
    for(int i = 1; i <= n; i++){
      lab_st[lab[i] = i].clear();
      active[i] = false;
    }
    vector<bool>s_in_st(n + 1, false);
    for(int i = 1; i <= m; i++){
      update_path(s[i], t[i], 1);
      in_topo[t2idm[t[i]] = i] = false;
      s_in_st[s[i]] = true;
      if(low[s[i]] <= low[t[i]] && tail[s[i]] >= low[t[i]]){
        for(int& vs : g[s[i]]){
          if(vs != par[s[i]] && low[vs] <= low[t[i]] && tail[vs] >= low[t[i]]){
            snear[i] = vs;
            break;
          }
        }
      }
      else{
        snear[i] = par[s[i]];
      }
    }
    for(int i = 1; i <= n; i++){
      if(!s_in_st[i]){
        work(i);
      }
    }
    for(int _ = 0; _ < m; _++){
      refine(1, 1, n);
      if(topo.empty()){
        return void(cout << "No\n");
      }
      int i = topo.front();
      topo.pop();
      update_path(s[i], t[i], -1);
      work(s[i]);
    }
    cout << "Yes\n";
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  int _t;
  cin >> _t;
  for(int _ = 0; _ < _t; _++){
    cin >> n;
    for(int i = 1; i <= n; i++){
      g[i].clear();
    }
    bool is_sub1 = true;
    for(int i = 1; i < n; i++){
      int a, b;
      cin >> a >> b;
      if(a != i || b != i + 1){
        is_sub1 = false;
      }
      g[a].push_back(b);
      g[b].push_back(a);
    }
    cin >> m;
    for(int i = 1; i <= m; i++){
      cin >> s[i] >> t[i];
    }   
    if(is_sub1){
      sub1::solve();
    }
    else if(_t <= 20 && n <= 250 && m == 2){
      sub2::solve();
    }
    else if(_t <= 20 && n <= 250 && m <= 6){
      sub3::solve();
    }
    else if(_t <= 20 && n <= 250 && m <= 100){
      sub4::solve();
    }
    else if(_t <= 20 && m <= 500){
      sub5::solve();
    }
    else{
      sub67::solve();
    }
  }
}

컴파일 시 표준 에러 (stderr) 메시지

jail.cpp: In function 'int main()':
jail.cpp:469:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  469 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...