NC17624 J.Ants(模拟)

目录

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;
}
posted @ 2021-10-18 16:44  Bcoi  阅读(45)  评论(0)    收藏  举报