제출 #1305478

#제출 시각아이디문제언어결과실행 시간메모리
1305478Zbyszek99Wild Boar (JOI18_wild_boar)C++20
47 / 100
18089 ms90096 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 ll INF = 1e18+50; const ll MOD = 1e9+7; struct path { int a,b; ll d; bool operator<(const path& other) const { return d < other.d; } }; vector<path> connection[2001][2001]; vector<pii> graph[2001]; ll cost[2005]; ll dist[2005]; bool is_bad[2005]; int n,m,q,L; const int tree_pot = 17; const int tree_siz = (1<<(tree_pot+1))-1; int arr[(1<<(tree_pot))+2]; struct node { int l,r; ll ans[6][6]; node() { rep(i,6) { rep(j,6) ans[i][j] = INF; } } node operator+(const node& other) { node res; res.l = l; res.r = other.r; rep(i,6) { rep(j,6) { rep(k,6) { res.ans[i][j] = min(res.ans[i][j],ans[i][k]+other.ans[k][j]+connection[arr[r]][arr[r+1]][k].d); } } } return res; } }; node nodes[tree_siz+1]; void upd_node(int v) { nodes[v] = nodes[v*2]+nodes[v*2+1]; } void set_beg_matrix(int ind) { int v = tree_siz/2+ind; rep(i,6) rep(j,6) nodes[v].ans[i][j] = INF; rep(i,6) rep(j,6) if(connection[arr[ind-1]][arr[ind]][i].b != connection[arr[ind]][arr[ind+1]][j].a) nodes[v].ans[i][j] = 0; } void upd_ind(int ind, int val) { arr[ind] = val; int v = tree_siz/2+ind; vi nums = {v}; vi nums2 = {}; if(ind != 1) nums.pb(v-1); if(v != tree_siz) nums.pb(v+1); forall(it,nums) set_beg_matrix(it-tree_siz/2); while(nums[0] != 1) { forall(it,nums) { bool was = 0; forall(it2,nums2) if(it2 == it/2) was = 1; if(!was) nums2.pb(it/2); } swap(nums,nums2); nums2 = {}; forall(it,nums) upd_node(it); } } void dijkstra(int beg, vi& bad, pll add = {-1,-1}) { forall(it,bad) is_bad[it] = 1; rep2(i,1,n) dist[i] = INF; priority_queue<pll,vector<pll>,greater<pll>> pq; pq.push({0,beg}); if(add.ff != -1) pq.push(add); while(!pq.empty()) { pll t = pq.top(); pq.pop(); if(dist[t.ss] != INF) continue; dist[t.ss] = t.ff; forall(it,graph[t.ss]) { if(!is_bad[it.ss]) pq.push({t.ff+cost[it.ss],it.ff}); } } forall(it,bad) is_bad[it] = 0; } int pop[2001]; ll find_cycle(int beg, vi& bad) { forall(it,bad) is_bad[it] = 1; rep2(i,1,n) dist[i] = INF; priority_queue<pair<ll,pii>,vector<pair<ll,pii>>,greater<pair<ll,pii>>> pq; pq.push({0,{beg,-1}}); while(!pq.empty()) { pair<ll,pii> t = pq.top(); pq.pop(); if(dist[t.ss.ff] != INF) continue; dist[t.ss.ff] = t.ff; pop[t.ss.ff] = t.ss.ss; forall(it,graph[t.ss.ff]) { if(!is_bad[it.ss]) pq.push({t.ff+cost[it.ss],{it.ff,it.ss}}); } } forall(it,bad) is_bad[it] = 0; ll ans = INF; rep2(i,1,n) { forall(it,graph[i]) { if(pop[i] != it.ss && pop[it.ff] != it.ss) ans = min(ans,dist[i]+dist[it.ff]+cost[it.ss]); } } return ans; } void calc_connection(int a, int b) { vector<path> paths; vi bad; forall(it,graph[b]) bad.pb(it.ss); forall(it,graph[a]) { if(it.ff == b) paths.pb({it.ss,it.ss,cost[it.ss]}); bad.pb(it.ss); ll cycle = find_cycle(it.ff,bad); dijkstra(it.ff,bad,{cycle+cost[it.ss],a}); forall(it2,graph[b]) { paths.pb({it.ss,it2.ss,dist[it2.ff]+cost[it.ss]+cost[it2.ss]}); } bad.pop_back(); } sort(all(paths)); int p1 = paths[0].a; int p2 = paths[0].b; vector<path> rel = {paths[0]}; forall(it,paths) { if(it.a != p1 && it.b != p2) { rel.pb(it); break; } } bool was = 0; forall(it,paths) { if(it.a != p1) { rel.pb(it); was = 1; break; } } if(was) { forall(it,paths) { if(it.a != p1 && it.b != rel.back().b) { rel.pb(it); was = 1; break; } } } was = 0; forall(it,paths) { if(it.b != p2) { rel.pb(it); was = 1; break; } } if(was) { forall(it,paths) { if(it.b != p2 && it.a != rel.back().a) { rel.pb(it); was = 1; break; } } } while(siz(rel) < 6) rel.pb(rel[0]); connection[a][b] = rel; } int main() { ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); //random_start(); cin >> n >> m >> q >> L; rep2(i,1,m) { int a,b; cin >> a >> b >> cost[i]; graph[a].pb({b,i}); graph[b].pb({a,i}); } rep2(i,0,n) { rep(k,6) { connection[0][i].pb({0,-1,0}); connection[i][0].pb({0,-1,0}); } } rep2(i,1,n) rep2(j,1,n) if(i != j) calc_connection(i,j); rep(i,L) cin >> arr[i+1]; rep2(i,tree_siz/2+1,tree_siz) { nodes[i].l = i-tree_siz/2; nodes[i].r = i-tree_siz/2; } rep2(i,1,tree_siz/2+1) upd_ind(i,arr[i]); rep(qq,q) { int p,val; cin >> p >> val; upd_ind(p,val); ll ans = INF; rep(i,6) rep(j,6) ans = min(ans,nodes[1].ans[i][j]); if(ans != INF) cout << ans << "\n"; else cout << "-1\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...