제출 #155341

#제출 시각아이디문제언어결과실행 시간메모리
155341ryanseeValley (BOI19_valley)C++14
100 / 100
1435 ms105420 KiB
#define LOCAL #include "bits/stdc++.h" using namespace std; #define FAST ios_base::sync_with_stdio(false); cin.tie(0); #define LLINF ((long long) 1e18)//1234567890987654321 #define INF 1234567890ll #define pb push_back #define eb emplace_back #define ins insert #define f first #define s second #define db 0 #define EPS (1e-7) //0.0000001 the value #define PI (acos((ld)-1.0)) #define MAXN (100006) #define ll long long int #define ld long double mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //can be used by calling rng() or shuffle(A, A+n, rng) #define FOR(ii, ss, ee) for(ll ii = ss; ii < (ll)ee; ++ii) #define space " " #define cbr cerr << "hi\n" #define mmst(x, v) memset((x), v, sizeof ((x))) #define siz(x) ((ll)x.size()) #define ph push #define btinpct(x) __builtin_popcountll((x)) #define all(x) (x).begin(), (x).end() #define lbd(x, y) lower_bound(all(x), y) #define ubd(x, y) upper_bound(all(x), y) typedef pair <int, ll> pi; typedef pair <int, pair<int,int>> spi; typedef pair <pi, pi> dpi; inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss string to_string(char c) {string s(1,c);return s;}string to_string(bool b){return (b ? "true" : "false");}template <typename A, typename B>string to_string(pair<A, B> p) {return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}template <typename A>string to_string(A v) {bool first = true;string res = "{";for (const auto &x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}void degug_out() { cerr << endl; }template <typename Head, typename... Tail>void degug_out(Head H, Tail... T) {cerr << " " << to_string(H);degug_out(T...);}inline ll gcd(ll a,ll b){if(a>b)swap(a,b);if(a==0)return b;return gcd(b%a,a);} #ifdef LOCAL #define degug(...) cerr << "[" << #__VA_ARGS__ << "]:", degug_out(__VA_ARGS__) #else #define degug(...) 42 #define cerr if(0)cout #endif #define sdb __attribute((optimize("-O3"),target("arch=sandybridge"))) ll n,shop,q,ep; vector<pi>shops; vector<pair<int,int>>v[MAXN]; pi edges[MAXN]; ll ans[MAXN]; int depth[MAXN], p[MAXN][21]; ll dist[MAXN]; int st[MAXN], en[MAXN], co=1; void sdb dfs(int x,int par){ st[x]=co++;p[x][0]=par; for(auto i:v[x])if(i.f!=par){ depth[i.f]=depth[x]+1; dist[i.f]=dist[x]+i.s; dfs(i.f,x); } en[x]=co; } bool sdb isp(int a,int b){return st[a]<=st[b]&&en[a]>=en[b];} int sdb lca(int x,int y){ if(isp(x,y))return x; if(isp(y,x))return y; for(int i=20;i>=0;--i){ if(!isp(p[x][i],y))x=p[x][i]; } return p[x][0]; } void sdb t2k() { for(int j=1;j<21;++j) for(int i=1;i<=n;++i) p[i][j]=p[p[i][j-1]][j-1]; } ll sdb disty(int x,int y){return dist[x]+dist[y]-2*dist[lca(x,y)];} multiset<ll>vals[MAXN]; int sz[MAXN], total=0, cp[MAXN], root; bitset<MAXN>used; struct centD { void sdb dfs1(ll x,ll p){ sz[x]=1; total++; for(auto i:v[x])if(i.f!=p&&!used[i.f]){ dfs1(i.f,x); sz[x]+=sz[i.f]; } } ll sdb dfs2(ll x,ll p){ for(auto i:v[x])if(i.f!=p&&sz[i.f]>total/2&&!used[i.f])return dfs2(i.f,x); return x; } void sdb main() { used=0; solve(ep,-1); } void sdb solve(ll x,ll p){ total=0; dfs1(x,p); ll c=dfs2(x,p); if(p==-1) { root=c; cp[c]=c; } else { cp[c]=p; } x=c; used[x]=1; for(auto i:v[x])if(!used[i.f]){ // v[i.f].erase(pi(x,i.s)); solve(i.f,x); } v[x].clear(); } void sdb update(ll x,ll o){ vals[x].ins(disty(x,o)); if(cp[x]^x) update(cp[x],o); } ll sdb query(ll x,ll o){ ll ans=(vals[x].size()?(*vals[x].begin()+disty(x,o)):LLINF); if(cp[x]^x) return min(ans,query(cp[x],o)); return ans; } void sdb re(ll x,ll o){ vals[x].erase(vals[x].find(disty(x,o))); if(cp[x]^x) re(cp[x],o); } } cen; vector<spi>more,moadd; ll sqn=1909; bool sdb cmp(spi x,spi y){ if(x.s.f/sqn==y.s.f/sqn) { return x.s.s<y.s.s; } else return x.s.f<y.s.f; } void sdb funny(){ vector<spi>mo2; for(auto i:more) if(i.s.f<=i.s.s) mo2.pb(i); else ans[i.f]=-5; more=mo2; } void sdb funny2(){ vector<spi>mo2; for(auto i:moadd) if(i.s.f<=i.s.s) mo2.pb(i); else ans[i.f]=-5; moadd=mo2; } int QQ[MAXN]; int sdb main() { FAST cin>>n>>shop>>q>>ep; FOR(i,1,n){ int a,b,c;cin>>a>>b>>c; v[a].pb(pi(b,c));v[b].pb(pi(a,c));edges[i]=pi(a,b); } dfs(ep,ep); t2k(); cen.main(); FOR(i,0,shop){ ll a;cin>>a;shops.eb(st[a],a); } sort(all(shops)); fill(ans,ans+q,LLINF); FOR(ii,0,q){ ll i,sp;cin>>i>>sp; QQ[ii]=sp; ll a=edges[i].f,b=edges[i].s; if(depth[a]>depth[b])swap(a,b); //~ cerr<<a<<' '<<sp<<' '<<ep<<' '<<lca(sp,ep)<<'\n'; if(isp(ep,a)&&isp(b,sp)){ if(shop==n) { ans[ii]=0; continue; } if(isp(b,sp)) { //~ mo.eb(ii,pi(st[ep],st[b]-1)); //~ if(en[b]<=en[ep]-1){mo.eb(ii,pi(en[b],en[ep]-1));} moadd.eb(ii,pi(st[b],en[b]-1)); } else { more.eb(ii,pi(st[b],en[b]-1)); } } else { ans[ii]=-LLINF; } } for(auto &i:more){ //~ cerr<<i.s.f<<' '<<i.s.s<<" became "; i.s.f=lbd(shops,pi(i.s.f,0))-shops.begin(); i.s.s=ubd(shops,pi(i.s.s,LLINF))-shops.begin()-1; //~ cerr<<i.s.f<<' '<<i.s.s<<'\n'; } funny(); sort(all(more),cmp); for(auto i:shops) cen.update(i.s,i.s); for(ll i=0;i<q;++i) if(ans[i]==-5) ans[i]=cen.query(QQ[i],QQ[i]); ll curl=0,curr=0; for(ll i=0;i<(int)more.size();i++){ ll L=more[i].s.f, R=more[i].s.s; ll ind=more[i].f; while(curr<=R){ cen.re(shops[curr].s,shops[curr].s); curr++; } while(curr-R>=2){ --curr; cen.update(shops[curr].s,shops[curr].s); } while(L<curl){ --curl;cen.re(shops[curl].s,shops[curl].s); } while(L>curl){ cen.update(shops[curl].s,shops[curl].s); ++curl; } /* answer here*/ //~ cerr<<ind<<' '<<QQ[ind]<<'\n'; ans[ind]=min(ans[ind],cen.query(QQ[ind], QQ[ind])); } //~ FOR(i,0,q) if(ans[i]==-LLINF) cout<<"escaped\n"; else if(ans[i]==LLINF) cout<<"oo\n"; else cout<<ans[i]<<'\n'; for(auto &i:moadd){ //~ cerr<<i.s.f<<' '<<i.s.s<<" became "; i.s.f=lbd(shops,pi(i.s.f,0))-shops.begin(); i.s.s=ubd(shops,pi(i.s.s,LLINF))-shops.begin()-1; //~ cerr<<i.s.f<<' '<<i.s.s<<'\n'; } funny2(); sort(all(moadd),cmp); FOR(i,0,MAXN)vals[i].clear(); //~ for(auto i:shops) cen.update(i.s,i.s); for(ll i=0;i<q;++i) if(ans[i]==-5) ans[i]=cen.query(QQ[i],QQ[i]); curl=0,curr=0; for(ll i=0;i<(int)moadd.size();i++){ ll L=moadd[i].s.f, R=moadd[i].s.s; ll ind=moadd[i].f; while(curr<=R){ cen.update(shops[curr].s,shops[curr].s); curr++; } while(curr-R>=2){ --curr; cen.re(shops[curr].s,shops[curr].s); } while(L<curl){ --curl;cen.update(shops[curl].s,shops[curl].s); } while(L>curl){ cen.re(shops[curl].s,shops[curl].s); ++curl; } /* answer here*/ //~ cerr<<ind<<' '<<QQ[ind]<<'\n'; ans[ind]=min(ans[ind],cen.query(QQ[ind], QQ[ind])); } FOR(i,0,q) if(ans[i]==-LLINF) cout<<"escaped\n"; else if(ans[i]==LLINF) cout<<"oo\n"; else cout<<ans[i]<<'\n'; } /* * 5 2 3 1 1 2 3 1 3 2 3 4 1 3 5 2 2 4 2 2 2 5 4 5 * 10 2 1 4 7 2 3 4 8 3 9 10 1 6 7 3 9 2 3 10 1 2 8 2 2 5 2 1 3 8 2 8 7 1 5 * 5 2 1 1 1 2 3 1 3 2 3 4 1 3 5 2 2 4 2 2 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...