結果
問題 | No.899 γatheree |
ユーザー | snow39 |
提出日時 | 2020-03-26 12:48:16 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 609 ms / 2,000 ms |
コード長 | 4,041 bytes |
コンパイル時間 | 1,288 ms |
コンパイル使用メモリ | 113,396 KB |
実行使用メモリ | 18,944 KB |
最終ジャッジ日時 | 2024-06-10 12:20:50 |
合計ジャッジ時間 | 13,115 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 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 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 553 ms
18,540 KB |
testcase_07 | AC | 565 ms
18,756 KB |
testcase_08 | AC | 609 ms
18,560 KB |
testcase_09 | AC | 578 ms
18,688 KB |
testcase_10 | AC | 596 ms
18,560 KB |
testcase_11 | AC | 585 ms
18,688 KB |
testcase_12 | AC | 570 ms
18,560 KB |
testcase_13 | AC | 565 ms
18,688 KB |
testcase_14 | AC | 555 ms
18,688 KB |
testcase_15 | AC | 568 ms
18,560 KB |
testcase_16 | AC | 564 ms
18,560 KB |
testcase_17 | AC | 551 ms
18,560 KB |
testcase_18 | AC | 584 ms
18,560 KB |
testcase_19 | AC | 580 ms
18,632 KB |
testcase_20 | AC | 551 ms
18,688 KB |
testcase_21 | AC | 387 ms
18,944 KB |
testcase_22 | AC | 388 ms
18,816 KB |
testcase_23 | AC | 395 ms
18,816 KB |
ソースコード
#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) 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 BFS_EulerTour{ vector<vector<int>> g; vector<int> par,dep; vector<int> in,out; vector<int> order,trans; vector<int> start;// don't init int D; int times; BFS_EulerTour(int V):g(V),par(V),dep(V),in(V),out(V),order(V),trans(V){} void add_edge(int a,int b){ g[a].push_back(b); g[b].push_back(a); } void dfs(int now,int p,int d){ in[now]=times++; dep[now]=d; par[now]=p; for(auto nex:g[now]) if(nex!=p) dfs(nex,now,d+1); out[now]=times; } void build(int root){ times=0; dfs(root,-1,0); D=*max_element(dep.begin(),dep.end())+1; queue<int> Q; Q.push(root); start.resize(D+1,-1); int cnt=0; while(!Q.empty()){ int now=Q.front();Q.pop(); if(start[dep[now]]==-1) start[dep[now]]=cnt; order[cnt]=now; trans[now]=cnt++; for(auto nex:g[now]) if(nex!=par[now]){ Q.push(nex); } } start[D]=(int)order.size(); } int lower_bound(int l,int r,int tar){//[l,r) int ok=r,ng=l-1; while(abs(ok-ng)>1){ int mid=(ok+ng)/2; if(tar<=in[order[mid]]) ok=mid; else ng=mid; } return ok; } pair<int,int> range(int v,int d){ if(dep[v]+d>=D) return {0,0}; int l=start[dep[v]+d]; int r=start[dep[v]+d+1]; return {lower_bound(l,r,in[v]),lower_bound(l,r,out[v])}; } }; class LazySegmentTree{ private: int n; vector<ll> node,lazy; vector<int> lz_flag; public: LazySegmentTree(vector<ll> v){ n=1; while(n<v.size()) n*=2; node.resize(2*n-1,0); lazy.resize(2*n-1,0); lz_flag.resize(2*n-1,0); for(int i=0;i<v.size();i++) node[i+n-1]=v[i]; for(int i=n-2;i>=0;i--) node[i]=node[2*i+1]+node[2*i+2]; } void eval(int k,int l,int r){ if(lz_flag[k]){ node[k]=lazy[k]*(r-l); if(r-l>1){ lz_flag[2*k+1]=1; lazy[2*k+1]=lazy[k]; lz_flag[2*k+2]=1; lazy[2*k+2]=lazy[k]; } lz_flag[k]=0; } } void update(int a,int b,ll x,int k=0,int l=0,int r=-1){ if(r<0) r=n; eval(k,l,r); if(b<=l||r<=a) return; if(a<=l&&r<=b){ lazy[k]=x; lz_flag[k]=1; eval(k,l,r); }else{ update(a,b,x,2*k+1,l,(r+l)/2); update(a,b,x,2*k+2,(r+l)/2,r); node[k]=node[2*k+1]+node[2*k+2]; } } ll getSum(int a,int b,int k=0,int l=0,int r=-1){ if(r<0) r=n; eval(k,l,r); if(b<=l||r<=a) return 0; if(a<=l&&r<=b) return node[k]; ll vl,vr; vl=getSum(a,b,2*k+1,l,(l+r)/2); vr=getSum(a,b,2*k+2,(l+r)/2,r); return vl+vr; } }; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N; cin>>N; BFS_EulerTour eul(N); rep(i,N-1){ int a,b; cin>>a>>b; eul.add_edge(a,b); } vector<ll> A(N); rep(i,N) cin>>A[i]; eul.build(0); vector<ll> v(N,0); rep(i,N) v[eul.trans[i]]=A[i]; LazySegmentTree seg(v); auto query=[&](int now,int d,ll &sum){ int l,r; tie(l,r)=eul.range(now,d); sum+=seg.getSum(l,r); seg.update(l,r,0); }; int Q; cin>>Q; rep(q,Q){ int x; cin>>x; ll ans=0; if(eul.par[x]!=-1){ int p=eul.par[x]; if(eul.par[p]!=-1) query(eul.par[p],0,ans); query(p,0,ans); query(p,1,ans); }else query(x,0,ans); query(x,1,ans); query(x,2,ans); cout<<ans<<"\n"; seg.update(eul.trans[x],eul.trans[x]+1,ans); } return 0; }