結果
問題 | No.1197 モンスターショー |
ユーザー |
![]() |
提出日時 | 2020-08-22 19:16:51 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 5,225 bytes |
コンパイル時間 | 1,769 ms |
コンパイル使用メモリ | 115,056 KB |
実行使用メモリ | 38,144 KB |
最終ジャッジ日時 | 2024-10-15 18:37:49 |
合計ジャッジ時間 | 26,807 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 40 TLE * 1 |
ソースコード
#include <iostream>#include <algorithm>#include <string>#include <vector>#include <cmath>#include <map>#include <queue>#include <iomanip>#include <set>#include <tuple>#define mkp make_pair#define mkt make_tuple#define rep(i,n) for(int i = 0; i < (n); ++i)#define all(v) v.begin(),v.end()using namespace std;typedef long long ll;const ll MOD=1e9+7;template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}struct LowestCommonAncestor{#define MAX_LOG_V 25vector<vector<int>> g;int root;vector<int> parent[MAX_LOG_V];vector<int> depth;LowestCommonAncestor(){}LowestCommonAncestor(int V,int root_):g(V),depth(V){root=root_;for(int i=0;i<MAX_LOG_V;i++) parent[i].resize(V);}void initialize(int V,int root_){g.resize(V);depth.resize(V,0);root=root_;for(int i=0;i<MAX_LOG_V;i++) parent[i].resize(V);}void add_edge(int u,int v){g[u].push_back(v);g[v].push_back(u);}void dfs(int v,int p,int d){parent[0][v]=p;depth[v]=d;for(int i=0;i<g[v].size();i++){if(g[v][i]!=p) dfs(g[v][i],v,d+1);}}void build(int V){dfs(root,-1,0);for(int k=0;k+1<MAX_LOG_V;k++){for(int v=0;v<V;v++){if(parent[k][v]<0) parent[k+1][v]=-1;else parent[k+1][v]=parent[k][parent[k][v]];}}}int query(int u,int v){if(depth[u]>depth[v]) swap(u,v);for(int k=0;k<MAX_LOG_V;k++){if((depth[v]-depth[u])>>k&1){v=parent[k][v];}}if(u==v) return u;for(int k=MAX_LOG_V-1;k>=0;k--){if(parent[k][u]!=parent[k][v]){u=parent[k][u];v=parent[k][v];}}return parent[0][u];}};struct Centroid{vector<vector<int>> g;vector<int> sz,dead;Centroid(){}Centroid(int V):sz(V,1),dead(V,0),g(V){}void initialize(int V){sz.resize(V,1);dead.resize(V,0);g.resize(V);}void add_edge(int u,int v){g[u].push_back(v);g[v].push_back(u);}int szdfs(int now,int par){sz[now]=1;for(auto nex:g[now]){if(nex==par||dead[nex]) continue;sz[now]+=szdfs(nex,now);}return sz[now];}void findCentroid(int now,int par,int V,vector<int> &cens){bool ok=true;for(auto nex:g[now]){if(nex==par||dead[nex]) continue;findCentroid(nex,now,V,cens);if(sz[nex]>V/2) ok=false;}if(V-sz[now]>V/2) ok=false;if(ok) cens.push_back(now);}vector<int> build(int root){vector<int> cens;szdfs(root,-1);findCentroid(root,-1,sz[root],cens);return cens;}void kill(int now){dead[now]=1;}bool alive(int now){return dead[now]==0;}};int parent[100010];ll sum[100010],num[100010];map<pair<int,int>,ll> mp;Centroid cent;LowestCommonAncestor lca;void decompose(int now,int par){vector<int> cs=cent.build(now);int C=cs[0];cent.kill(C);parent[C]=par;for(auto nex:cent.g[C]){if(cent.alive(nex)) decompose(nex,C);}}void paint(int target,bool f){int v=target;while(v!=-1){int u=lca.query(target,v);int cost=lca.depth[target]+lca.depth[v]-2*lca.depth[u];if(parent[v]!=-1){int t=lca.query(target,parent[v]);int tmp=lca.depth[target]+lca.depth[parent[v]]-2*lca.depth[t];if(f){mp[mkp(parent[v],v)]+=tmp;}else{mp[mkp(parent[v],v)]-=tmp;}}if(f){sum[v]+=cost;num[v]++;}else{sum[v]-=cost;num[v]--;}v=parent[v];}}ll query(int target){ll res=0;int v=target;while(v!=-1){int u=lca.query(target,v);int cost=lca.depth[target]+lca.depth[v]-2*lca.depth[u];res+=sum[v]+cost*num[v];if(parent[v]!=-1){int t=lca.query(target,parent[v]);int tmp=lca.depth[target]+lca.depth[parent[v]]-2*lca.depth[t];res-=(mp[mkp(parent[v],v)]+(tmp)*num[v]);}v=parent[v];}return res;}int main(){cin.tie(0);ios::sync_with_stdio(false);int N,K,Q;cin>>N>>K>>Q;vector<int> C(K);rep(i,K) cin>>C[i];rep(i,K) C[i]--;vector<int> U(N-1),V(N-1);rep(i,N-1) cin>>U[i]>>V[i];rep(i,N-1){U[i]--;V[i]--;}cent.initialize(N);rep(i,N-1) cent.add_edge(U[i],V[i]);lca.initialize(N,0);rep(i,N-1) lca.add_edge(U[i],V[i]);lca.build(N);decompose(0,-1);rep(i,K) paint(C[i],true);for(int q=0;q<Q;q++){int t;cin>>t;if(t==1){int p,d;cin>>p>>d;p--;d--;paint(C[p],false);C[p]=d;paint(C[p],true);}else{int e;cin>>e;e--;cout<<query(e)<<"\n";}}return 0;}