結果

問題 No.529 帰省ラッシュ
ユーザー hashiryohashiryo
提出日時 2019-06-09 11:32:12
言語 C++14
(gcc 13.2.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 6,335 bytes
コンパイル時間 2,722 ms
コンパイル使用メモリ 195,216 KB
実行使用メモリ 47,828 KB
最終ジャッジ日時 2024-04-15 20:04:43
合計ジャッジ時間 10,380 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 AC 288 ms
47,828 KB
testcase_14 AC 372 ms
21,564 KB
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>

#define debug(x) cerr << #x << ": " << x << '\n'
#define debugArray(x,n) for(long long hoge = 0; (hoge) < (n); ++ (hoge)) cerr << #x << "[" << hoge << "]: " << x[hoge] << '\n'
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> vll;
const ll INF = INT_MAX;
const ll MOD = 998244353;

struct Edge{
  int src,dst;
  Edge(ll s,ll t):src(s),dst(t){}
};
using Edges=vector<Edge>;
using Graph=vector<Edges>;

struct BridgeBlockTree{
    vector<int> index;
    vector<vector<int>> block;
    Edges bridges;
    Graph g;
    BridgeBlockTree(Graph g_){
        ll n=g_.size();
        index.assign(n, -1);
        vector<int> num(n), par(n,-1), cur(n);
        for (int s = 0; s < n; ++s) {
            if (num[s]) continue;
            int time = 0;
            vector<int> snum, path, stack = {s};
            while (!stack.empty()) {
                int u = stack.back();
                if (cur[u] == 0) {
                    num[u] = ++time;
                    path.push_back(u);
                    snum.push_back(num[u]);
                }
                if(cur[u] == (ll)g_[u].size()){
                    if (num[u] == snum.back()){
                        snum.pop_back();
                        block.push_back({});
                        while (1) {
                            int w = path.back(); path.pop_back();
                            block.back().push_back(w);
                            index[w] = block.size()-1;
                            if (u == w) break;
                        }
                    }
                    stack.pop_back();
                }else{
                    int v = g_[u][cur[u]++].dst;
                    if (!num[v]) {
                        par[v] = u;
                        stack.push_back(v);
                    }else if (v != par[u] && index[v] < 0) {
                        while (snum.back() > num[v]) snum.pop_back();
                    }
                }
            }
        }
        ll tn = block.size();
        g.resize(tn);
        for (int u = 0; u < n; ++u)if(par[u] >= 0 && index[u] != index[par[u]]){
            g[index[u]].emplace_back(index[u], index[par[u]]);
            g[index[par[u]]].emplace_back(index[par[u]],index[u]);
            bridges.emplace_back(index[u],index[par[u]]);
        }
    }
    int operator[](const int &k){
        return index[k];
    }
};

struct HLDecomposition{
private:
    int t;
    void dfs_size(int v=0){
        size[v]=1;
        for(Edge& e:g[v]){
            if(par[e.dst]>=0){
                swap(e,g[v].back());
                if(e.dst==g[v].back().dst)continue;
            }
            par[e.dst]=v;
            dfs_size(e.dst);
            size[v]+=size[e.dst];
            if(size[e.dst]>size[g[v][0].dst]){
                swap(e,g[v][0]);
            }
        }
    }
    void dfs_hld(int v=0,int d=0){
        in[v] = t++;
        inv[in[v]]=v;
        dep[v] = d;
        for(Edge& e:g[v]){
            if(par[e.dst]!=v)continue;
            head[e.dst]=(e.dst==g[v][0].dst?head[v]:e.dst);
            dfs_hld(e.dst,d+1);
        }
        out[v]=t;
    }
public:
    int V;
    Graph g;
    vector<int> dep,par,head,size,inv;
    vector<int> in,out;
    HLDecomposition(int size_)
    :t(0),V(size_),g(V),dep(V,0),par(V,-1),head(V),size(V),inv(V),in(V),out(V){}
    HLDecomposition(Graph g_)
    :t(0),V(g_.size()),g(g_),dep(V,0),par(V,-1),head(V),size(V),inv(V),in(V),out(V){}
    void add_edge(int u,int v){
        g[u].emplace_back(u,v);
        g[v].emplace_back(v,u);
    }
    void build(int root=0){
        par[root]=0;
        dfs_size(root);
        par[root]=-1;
        dfs_hld(root);
    }
    int lca(int u,int v){
        while(1){
            if(in[u]>in[v])swap(u,v);
            if(head[u]==head[v])return u;
            v=par[head[v]];
        }
    }
    int distance(int u,int v){
        return dep[u]+dep[v]-2*dep[lca(u,v)];
    }
    int operator[](const int &k){
        return in[k];
    }
};

template <typename M>
struct SegmentTree{
    using T = typename M::T;
    int n;
    vector<T> dat;
    SegmentTree(){}
    SegmentTree(int n_){init(n_);}
    SegmentTree(const vector<T> &v){build(v);}
    void init(int n_){
        n=1;
        while(n<n_) n<<=1;
        dat.assign(n<<1,M::ti());
    }
    void build(const vector<T> &v){
        int n_=v.size();
        init(n_);
        for(int i=0;i<n_;i++) dat[n+i]=v[i];
        for(int i=n-1;i;i--)
            dat[i]=M::f(dat[(i<<1)|0],dat[(i<<1)|1]);
    }
    void set_val(int k,T x){
        dat[k+=n]=x;
        while(k>>=1)
            dat[k]=M::f(dat[(k<<1)|0],dat[(k<<1)|1]);
    }
    //[a,b)
    T query(int a,int b,int k=1,int l=0,int r=-1){
        if(r<0)r=n;
        if(r<=a||b<=l) return M::ti();
        if(a<=l&&r<=b) return dat[k];
        T vl=query(a,b,k*2,l,(l+r)/2);
        T vr=query(a,b,k*2+1,(l+r)/2,r);
        return M::f(vl,vr);
    }
    T operator[](const int &k) const {return dat[k + n];}
};

struct RmaxQ {
    struct T{
      ll val,idx;
      T(ll v,ll i):val(v),idx(i){}
    };
    static T ti() { return {-1,0}; }
    static T f(const T& l, const T & r) { return l.val>r.val? l:r; }
};

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll N,M,Q;cin>>N>>M>>Q;
  Graph g(N);
  for(ll i=0;i<M;i++){
    ll x,y;cin>>x>>y;x--;y--;
    g[x].emplace_back(x,y);
    g[y].emplace_back(y,x);
  }
  BridgeBlockTree bbt(g);
  HLDecomposition hld(bbt.g);
  hld.build();
  SegmentTree<RmaxQ> seg(hld.V);
  for(ll i=0;i<hld.V;i++){
    seg.set_val(i,{-1,i});
  }
  vector<priority_queue<ll>> que(hld.V);
  for(ll i=0;i<hld.V;i++){
    que[i].push(-1);
  }
  for(ll q=0;q<Q;q++){
    ll op;cin>>op;
    if(op&1){
      ll U,W;cin>>U>>W;U--;
      ll u=bbt[U];
      que[u].push(W);
      seg.set_val(u,{que[u].top(),u});
    }else{
      ll S,T;cin>>S>>T;S--;T--;
      ll u=bbt[S],v=bbt[T];
      RmaxQ::T ans=RmaxQ::ti();
      while(1){
        if(hld[u]>hld[v])swap(u,v);
        ans = RmaxQ::f(ans,seg.query(max(hld[u],hld[hld.head[v]]),hld[v]+1));
        if(hld.head[u]!=hld.head[v])v=hld.par[hld.head[v]];
        else break;
      }
      cout<<ans.val<<endl;
      if(ans.val>=0){
        que[ans.idx].pop();
        seg.set_val(ans.idx,{que[ans.idx].top(),ans.idx});
      }
    }
  }

  return 0;
}
0