NC17624 J.Ants(模擬)
阿新 • • 發佈:2021-10-18
目錄
Description
有一個長度為 \([0,1e9+1]\) 的木棍,上面有 \(n\) 個螞蟻,但是在木棍的端點有兩個障礙物,牢固值分別為 \(A, B\),如果有一個螞蟻裝上障礙物,對應端點的牢固值減一,當 \(A/B=0\) 時,障礙物剛好消失;
現在這 \(n\) 個螞蟻分別向左或向右行走,如果碰到了螞蟻或者是障礙物都會掉頭,每隻螞蟻速度為 \(1m/s\)
State
\(1<=n<=10^6\)
\(1<=A<=B<=10^9\)
\(1<=a_1,a_2...a_n<=10^9\)
\(d_1,d_2...d_n∈{0,1}\)
Input
2 2 4
2 3
0 1
Output
4000000001
Solution
題目需要一個小技巧,我們不考慮螞蟻相撞,這樣當第 \(i\) 只螞蟻回到原來的位置是,其需要花費 \(2e9+2\) 的時間,並且對兩端的障礙物都造成一次傷害,這樣 \(A,B\) 的範圍就降為了 \(1e6\)
而此時所有的螞蟻還是處於原來的狀態,剩下的就是模擬了
假設有一個數組 \(p[i]\) 表示的是到其所對應的端點的距離是多少,然後按升序排序,其中有一個螞蟻比較特殊,即 \(x\),任意的 \(i>x\) ,都會掉下去
而這個 \(x\) 所花費的時間就是這次路程的最長時間,對於其之前還沒有掉下去的螞蟻來說,需要對其進行更新其當前位置
Code
const int N = 1e6 + 5; int n, m, k, _; // int a[N]; pli p[N]; ll sum[N]; ll calc(int a, int b) { ll ans = 0; while(true){ int tot = 0; ll maxx = 0; for(int i = 1; i <= n; i ++){ if(p[i].se == -1) continue; sum[i] = p[i].fi; maxx = p[i].fi; //最長時間 int id = p[i].se; if(id == 1){ if(b == 0){ p[i].se = -1; } else{ b --; p[i] = {1e9 + 1, 0}; } } else if(id == 0){ if(a == 0){ p[i].se = -1; } else{ a --; p[i] = {1e9 + 1, 1}; } } } ans += maxx; for(int i = 1; i <= n; i ++){ p[i].fi = p[i].fi - maxx + sum[i]; if(p[i].se == -1) tot ++; } if(tot == n) break; } return ans; } signed main() { // IOS; int a, b; while(~ sddd(n, a, b)){ ll ans = 0; rep(i, 1, n){ sll(p[i].fi); } rep(i, 1, n){ sd(p[i].se); } rep(i, 1, n){ if(p[i].se == 1){ p[i].fi = 1e9 + 1 - p[i].fi; } } sort(p + 1, p + 1 + n); int minn = min(a, b); ll k = minn / n; a -= k * n; b -= k * n; ans += 2 * k * (ll)(1e9 + 1); ans += calc(a, b); pll(ans); } // PAUSE; return 0; }