結果

問題 No.529 帰省ラッシュ
ユーザー chocoruskchocorusk
提出日時 2019-10-01 23:58:55
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 460 ms / 4,500 ms
コード長 4,674 bytes
コンパイル時間 1,427 ms
コンパイル使用メモリ 134,640 KB
実行使用メモリ 47,268 KB
最終ジャッジ日時 2024-10-03 05:49:16
合計ジャッジ時間 8,981 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
6,816 KB
testcase_01 AC 3 ms
6,816 KB
testcase_02 AC 3 ms
6,816 KB
testcase_03 AC 3 ms
6,816 KB
testcase_04 AC 9 ms
6,820 KB
testcase_05 AC 8 ms
6,816 KB
testcase_06 AC 9 ms
6,820 KB
testcase_07 AC 9 ms
6,816 KB
testcase_08 AC 412 ms
20,532 KB
testcase_09 AC 398 ms
20,976 KB
testcase_10 AC 401 ms
27,680 KB
testcase_11 AC 408 ms
27,836 KB
testcase_12 AC 356 ms
22,848 KB
testcase_13 AC 299 ms
47,268 KB
testcase_14 AC 399 ms
26,516 KB
testcase_15 AC 458 ms
31,200 KB
testcase_16 AC 454 ms
31,228 KB
testcase_17 AC 429 ms
43,312 KB
testcase_18 AC 460 ms
43,864 KB
testcase_19 AC 429 ms
40,292 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
vector<int> g[100010];
int order[100010];
vector<int> s;
bool ins[100010];
vector<int> roots;
vector<P> bridge;
vector<vector<int>> tree;
vector<vector<int>> eachbcc;
int cmp[100010];
void dfs(int x, int prev, int &k){
	order[x]=k;
	k++;
	s.push_back(x);
	ins[x]=1;
	roots.push_back(x);
	for(auto y:g[x]){
		if(order[y]==0){
			dfs(y, x, k);
		}else if(y!=prev && ins[y]){
			while(order[roots.back()]>order[y]) roots.pop_back();
		}
	}
	if(x==roots.back()){
		if(prev!=-1) bridge.push_back({prev, x});
		vector<int> bcc;
		while(1){
			int node=s.back(); s.pop_back();
			ins[node]=0;
			bcc.push_back(node);
			cmp[node]=eachbcc.size();
			if(node==x) break;
		}
		eachbcc.push_back(bcc);
		roots.pop_back();
	}
}

using PQ=priority_queue<P>;
vector<P> seg;
vector<PQ> que;
int sz;
void update(int k, P x){
	que[k].push(x);
	k+=sz;
	if(seg[k]>=x) return;
	seg[k]=x;
	while(k>1){
		k>>=1;
		seg[k]=max(seg[2*k], seg[2*k+1]);
	}
}
P query(int a, int b){
	a+=sz, b+=sz;
	P ret=P(-1, -1);
	for(;a<b; a>>=1, b>>=1){
		if(b&1) ret=max(ret, seg[--b]);
		if(a&1) ret=max(ret, seg[a++]);
	}
	return ret;
}
void erase(int k){
	que[k].pop();
	k+=sz;
	if(que[k-sz].empty()) seg[k]=P(-1, -1);
	else seg[k]=que[k-sz].top();
	while(k>1){
		k>>=1;
		seg[k]=max(seg[2*k], seg[2*k+1]);
	}
}

template< typename G >
struct HeavyLightDecomposition {
  G &g;
  vector< int > sz, in, out, head, rev, par;

  HeavyLightDecomposition(G &g) :
      g(g), sz(g.size()), in(g.size()), out(g.size()), head(g.size()), rev(g.size()), par(g.size()) {}

  void dfs_sz(int idx, int p) {
    par[idx] = p;
    sz[idx] = 1;
    if(g[idx].size() && g[idx][0] == p) swap(g[idx][0], g[idx].back());
    for(auto &to : g[idx]) {
      if(to == p) continue;
      dfs_sz(to, idx);
      sz[idx] += sz[to];
      if(sz[g[idx][0]] < sz[to]) swap(g[idx][0], to);
    }
  }

  void dfs_hld(int idx, int par, int &times) {
    in[idx] = times++;
    rev[in[idx]] = idx;
    for(auto &to : g[idx]) {
      if(to == par) continue;
      head[to] = (g[idx][0] == to ? head[idx] : to);
      dfs_hld(to, idx, times);
    }
    out[idx] = times;
  }

  void build() {
    dfs_sz(0, -1);
    int t = 0;
    dfs_hld(0, -1, t);
  }

  int la(int v, int k) {
    while(1) {
      int u = head[v];
      if(in[v] - k >= in[u]) return rev[in[v] - k];
      k -= in[v] - in[u] + 1;
      v = par[u];
    }
  }

  int lca(int u, int v) {
    for(;; v = par[head[v]]) {
      if(in[u] > in[v]) swap(u, v);
      if(head[u] == head[v]) return u;
    }
  }

  template< typename T, typename Q, typename F >
  T query(int u, int v, const T &ti, const Q &q, const F &f, bool edge = false) {
    T l = ti;//, r = ti;
    for(;; v = par[head[v]]) {
      if(in[u] > in[v]) swap(u, v);//, swap(l, r);
      if(head[u] == head[v]) break;
	  l = f(q(in[head[v]], in[v] + 1), l);
    }
    //return f(f(q(in[u] + edge, in[v] + 1), l), r);
	return f(q(in[u] + edge, in[v] + 1), l);
//  return {f(q(in[u] + edge, in[v] + 1), l), r};
  }

  template< typename Q >
  void add(int u, int v, ll x, const Q &q, bool edge = false) {
    for(;; v = par[head[v]]) {
      //if(in[u] > in[v]) swap(u, v);
      if(head[u] == head[v]) break;
      q(in[head[v]], in[v] + 1, x);
    }
    q(in[u] + edge, in[v] + 1, x);
  }
};

int main()
{
	int n, m, Q;
	cin>>n>>m>>Q;
	for(int i=0; i<m; i++){
		int a, b;
		cin>>a>>b;
		a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	int k=1;
	dfs(0, -1, k);
	int N=bridge.size()+1;
	tree.resize(N);
	for(auto e:bridge){
		int x=cmp[e.first], y=cmp[e.second];
		tree[x].push_back(y);
		tree[y].push_back(x);
	}
	HeavyLightDecomposition<vector<vector<int>>> hld(tree);
	hld.build();

	auto f=[](P a, P b){ return max(a, b);};
	sz=1;
	while(sz<N) sz<<=1;
	seg.resize(2*sz, P(-1, -1));
	que.resize(N);
	auto q=[&](int a, int b){
		return query(a, b);
	};

	for(int i=0; i<Q; i++){
		char c;
		cin>>c;
		if(c=='1'){
			int u, w;
			cin>>u>>w;
			u--;
			update(hld.in[cmp[u]], P(w, u));
		}else{
			int s, t;
			cin>>s>>t;
			s--; t--;
			P p=hld.query(cmp[s], cmp[t], P(-1, -1), q, f);
			if(p.first==-1){
				printf("-1\n");
				continue;
			}
			printf("%d\n", p.first);
			erase(hld.in[cmp[p.second]]);
		}
	}
	return 0;
}
0