Submission #1289433

#TimeUsernameProblemLanguageResultExecution timeMemory
1289433Zbyszek99Board Game (JOI24_boardgame)C++20
100 / 100
1894 ms205424 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; struct fri { ll c1,c2,opt; bool operator<(const fri& other) const { return opt<other.opt; } }; vi graph[50001]; bool is_stop[50001]; bool is_double[50001]; ll dist1[50001]; ll dist2[50001]; ll dist3[50001][2]; ll dist_double[50001]; ll fr_mul[50001]; ll fr_const[50001]; ll dist_layer[50001][501]; ll dist_stop[50001]; int n,m,k; void bfs(vi begs, ll* dist, ll is) { priority_queue<pll,vector<pll>,greater<pll>> q; rep2(i,1,n) dist[i] = 1e9; forall(it,begs) q.push({0,it}); while(!q.empty()) { pii t = q.top(); q.pop(); if(dist[t.ss] != 1e9) continue; dist[t.ss] = t.ff; forall(it,graph[t.ss]) { q.push({t.ff+(is_stop[t.ss] ? is : 1),it}); } } } void bfs2(int beg, ll add) { priority_queue<pair<ll,pii>,vector<pair<ll,pii>>,greater<pair<ll,pii>>> q; rep2(i,1,n) rep(d,2) dist3[i][d] = 1e9; q.push({0,{beg,0}}); while(!q.empty()) { pair<ll,pii> t = q.top(); q.pop(); if(dist3[t.ss.ff][t.ss.ss] != 1e9) continue; dist3[t.ss.ff][t.ss.ss] = t.ff; forall(it,graph[t.ss.ff]) { q.push({t.ff+(is_stop[t.ss.ff] ? add : 1),{it,max(t.ss.ss,(int)(is_stop[t.ss.ff] && t.ss.ff != beg))}}); } } } void bfs1(int v) { queue<pii> q; q.push({v,0}); rep2(i,1,n) dist1[i] = 1e18; while(!q.empty()) { pii t = q.front(); q.pop(); if(dist1[t.ff] != 1e18) continue; dist1[t.ff] = t.ss; if(is_stop[t.ff] && t.ff != v) continue; forall(it,graph[t.ff]) { q.push({it,t.ss+1}); } } } void bfs_stop(int beg) { priority_queue<pii,vector<pii>,greater<pii>> pq; pq.push({0,beg}); rep2(i,1,n) dist_stop[i] = 1e9; while(!pq.empty()) { pii t = pq.top(); pq.pop(); if(dist_stop[t.ss] != 1e9) continue; dist_stop[t.ss] = t.ff; forall(it,graph[t.ss]) { pq.push({t.ff+(t.ss != beg && is_stop[t.ss]),it}); } } } void bfs_layer(int beg) { queue<pair<int,pii>> q; q.push({0,{beg,0}}); rep2(i,1,n) rep2(j,0,500) dist_layer[i][j] = 1e18; while(!q.empty()) { pair<int,pii> t = q.front(); q.pop(); if(t.ss.ss > 500 || dist_layer[t.ss.ff][t.ss.ss] != 1e18) continue; dist_layer[t.ss.ff][t.ss.ss] = t.ff; int my_dist = dist_stop[t.ss.ff]+t.ss.ss; int add = is_stop[t.ss.ff] && !(t.ss.ss == 0 && t.ss.ff == beg); forall(it,graph[t.ss.ff]) { q.push({t.ff+1,{it,my_dist+add-dist_stop[it]}}); } } } int main() { ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); //random_start(); cin >> n >> m >> k; rep(i,m) { int a,b; cin >> a >> b; graph[a].pb(b); graph[b].pb(a); } string s; cin >> s; rep(i,n) { if(s[i] == '1') is_stop[i+1] = 1; } vi fr(k-1); int beg = 0; rep(i,k) { if(i != 0) cin >> fr[i-1]; else cin >> beg; } bfs1(beg); bfs({beg},dist2,1); bool was = 0; rep2(i,1,n) if(dist1[i] != dist2[i]) was = 1; if(!was) { rep2(i,1,n) cout << dist1[i] << "\n"; return 0; } rep2(i,1,n) if(is_stop[i]) forall(it,graph[i]) if(is_stop[it]) is_double[i] = 1; vi begs; rep2(i,1,n) if(is_stop[i]) begs.pb(i); bfs(begs,dist_stop,1); begs = {}; rep2(i,1,n) if(is_double[i]) begs.pb(i); bfs(begs,dist_double,0); vector<fri> lines; forall(it,fr) { ll c1 = dist_stop[it]-2; ll c2 = dist_double[it]; if(is_stop[it]) { c1 = 0; } lines.pb({c1,c2,c2-c1}); } sort(all(lines)); rep2(i,1,n) dist2[i] = 1e18; if(k <= 100) { rep2(i,0,siz(lines)) { ll add = 2*siz(lines)-i; ll add_const = 0; rep(j,i) add_const += lines[j].c2; rep2(j,i,siz(lines)-1) add_const += lines[j].c1; bfs2(beg,add+1); rep2(i,1,n) dist3[i][1] += add_const; if(is_stop[beg]) rep2(i,1,n) dist3[i][1] -= add; rep2(j,1,n) { dist2[j] = min(dist2[j],dist3[j][1]); } } } else { forall(it,lines) { fr_mul[0] += 2; fr_const[0] += it.c1; if(it.opt <= n) { fr_mul[max(0,(int)it.opt)]--; fr_const[max(0,(int)it.opt)] += -it.c1+it.c2; } } rep2(i,1,n) { fr_mul[i] += fr_mul[i-1]; fr_const[i] += fr_const[i-1]; } fr_mul[0] = 0; fr_const[0] = 0; bfs_stop(beg); bfs_layer(beg); rep2(i,1,n) { rep2(d,0,500) { if(dist_stop[i] == 0 && d == 0) continue; if(dist_stop[i]+d > n) break; dist2[i] = min(dist2[i],fr_mul[dist_stop[i]+d]*(dist_stop[i]+d)+fr_const[dist_stop[i]+d]+dist_layer[i][d]); } } } rep2(i,1,n) { cout << min(dist1[i],dist2[i]) << "\n"; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...