Submission #1187074

#TimeUsernameProblemLanguageResultExecution timeMemory
1187074mychecksedadRigged Roads (NOI19_riggedroads)C++20
37 / 100
1031 ms327680 KiB
/* Author : Mychecksdead  */
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define MOD (1000000000+7)
#define MOD1 (998244353)
#define pb push_back
#define all(x) x.begin(), x.end()
#define en cout << '\n'
#define ff first
#define ss second
#define pii pair<int,int>
#define vi vector<int>
const int N = 3e5+100, M = 1e5+10, K = 19, MX = 30;


int n, m, tin[N], tout[N], timer = 1, sz[N], heavy[N], up[N][K];
vector<pii> g[N];
vector<pii> E;
bitset<N> in;
set<int> T[1200005];

void add(int l, int r, int p, int k, int val){
  T[k].insert(val);
  if(l == r){
    return;
  }
  int mid=l+r>>1;
  if(p <= mid) add(l, mid, p, k<<1, val);
  else add(mid+1, r, p, k<<1|1, val);
}
void rem(int l, int r, int p, int k, int val){
  T[k].erase(val);
  if(l == r){
    return;
  }
  int mid=l+r>>1;
  if(p <= mid) rem(l, mid, p, k<<1, val);
  else rem(mid+1, r, p, k<<1|1, val);
}
int range[10000], ptr;
void get_range(int l, int r, int ql, int qr, int k){
  if(ql > r || l > qr) return;
  if(ql <= l && r <= qr){
    range[ptr++] = k;
    return;
  }
  int mid = l+r>>1;
  get_range(l, mid, ql, qr, k<<1);
  get_range(mid+1, r, ql, qr, k<<1|1);
}


void pre(int v, int p){
  sz[v] = 1;
  for(auto &E: g[v]){
    int u = E.ff;
    if(u != p){
      pre(u, v);
      sz[v] += sz[u];
      if(g[v][0].ff == p || sz[g[v][0].ff] < sz[u]){
        swap(g[v][0], E);
      }
    }
  }
}
void dfs(int v, int p){
  tin[v] = timer++;
  for(auto [u, idx]: g[v]){
    if(u==p)continue;
    up[u][0] = v;
    if(u == g[v][0].ff) heavy[u] = heavy[v];
    else heavy[u] = u;
    dfs(u, v);
    add(1, n, tin[u], 1, idx);
  }
  tout[v] = timer - 1;
}

bool is_anc(int u, int v){
  return tin[u] <= tin[v] && tout[v] <= tout[u];
}

int _lca(int u, int v){
  if(is_anc(u, v)) return u;
  if(is_anc(v, u)) return v;
  for(int j = K-1; j >= 0; --j){
    if(!is_anc(up[u][j], v)) u = up[u][j];
  }
  return up[u][0];
}

void solve(){
  cin >> n >> m;
  for(int i = 1; i <= m; ++i){
    int u, v; cin >> u >> v;
    E.pb({u, v});
  }
  for(int i = 1; i < n; ++i){
    int x; cin >> x;
    int u = E[x-1].ff, v = E[x-1].ss;
    g[u].pb({v, x-1});
    g[v].pb({u, x-1});
    in[x - 1] = 1;
  }

  heavy[1] = 1;
  pre(1, 1);
  dfs(1, 1);
  up[1][0] = 1;

  for(int j = 1; j < K; ++j){
    for(int i = 1; i <= n; ++i){
      up[i][j] = up[up[i][j - 1]][j - 1];
    }
  }

  vector<int> ans(m + 1, -1);
  vi W;
  for(int i = m; i >= 1; --i){
    W.pb(i);
  }

  for(int i = 0; i < m; ++i){
    if(ans[i] != -1) continue;
    if(in[i]){
      ans[i] = W.back();
      W.pop_back();
      if(tin[E[i].ff] > tin[E[i].ss]){
        rem(1, n, tin[E[i].ff], 1, i);
      }else{
        rem(1, n, tin[E[i].ss], 1, i);
      }
    }else{
      int u = E[i].ff, v = E[i].ss;
      int lca = _lca(u, v);

      ptr = 0;

      for(int rep = 0; rep < 2; ++rep){
        while(u != lca){
          if(tin[heavy[u]] > tin[lca]){
            get_range(1, n, tin[heavy[u]], tin[u], 1);
            u = up[heavy[u]][0];
          }else{
            get_range(1, n, tin[lca] + 1, tin[u], 1);
            break;
          }
        }
        swap(u, v);
      }


      priority_queue<pair<int, int>> Q; // position, id
      for(int i = 0; i < ptr; ++i){
        int x = range[i];
        if(T[x].size())
          Q.push({-(*T[x].begin()), x});
      }
      while(!Q.empty()){
        int v = Q.top().ff, x = Q.top().ss; Q.pop();

        v = -v;
        if(tin[E[v].ff] > tin[E[v].ss]){
          rem(1, n, tin[E[v].ff], 1, v);
        }else{
          rem(1, n, tin[E[v].ss], 1, v);
        }

        ans[v] = W.back();
        W.pop_back();

        if(T[x].size()){
          Q.push({-(*T[x].begin()), x});
        }
      }
      ans[i] = W.back();
      W.pop_back();
    }
  }
  for(int i = 0; i < m; ++i){
    cout << ans[i] << ' ';
  }
}


int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  int tt = 1, aa;
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  while(tt--){
    solve();
    en;
  }
  cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\n";
  return 0;
} 
#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...