zoukankan      html  css  js  c++  java
  • CodeForces 1295E Permutation Separation

    题意

    给定一个排列(p),和一数组(a),任意取一数(k)(1leq k<n)),将排列分为两个序列(p_1),(p_2),...,(p_k)(p_{k+1}),(p_{k+2}),...,(p_{n}),然后将两个序列中的某些数移到另一个序列,使得第一个序列中的数小于第二个序列中的所有数(任意一个序列为空也可),移动(p[i])的花费为(a[i]),问最小花费

    分析

    (j)为操作完后左半序列的元素个数,易知左半部分的数为(1)-(j),右半部分的数为(j+1)-(n)

    对于一个数(p[i]),如果将其分在左半边,则

    • (j>=p[i]),则花费不变
    • (j<p[i]),则花费需加上(a[i])

    因此先假设所有的元素都在右半部分,枚举(1)-(n-1),枚举(k),每次更新(p[k])的贡献,由上述可知(p[k])([1,p[i]-1])贡献为(a[i]),而因为一开始所有元素都在右半部分,所以对([p[i],n])的贡献为(-a[i]),每次用线段树全局最小值更新答案

    #pragma GCC optimize(3, "Ofast", "inline")
    
    #include <bits/stdc++.h>
    
    using namespace std;
    
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define ll long long
    #define int ll
    #define ls st<<1
    #define rs st<<1|1
    #define pii pair<int,int>
    #define rep(z, x, y) for(int z=x;z<=y;++z)
    #define com bool operator<(const node &b)
    const int maxn = (ll) 2e5 + 5;
    const int mod = 998244353;
    const int inf = 0x3f3f3f3f;
    int T = 1;
    int t[maxn << 2], tag[maxn << 2];
    
    void push_down(int st) {
        if (!tag[st])
            return;
        t[ls] += tag[st];
        t[rs] += tag[st];
        tag[ls] += tag[st];
        tag[rs] += tag[st];
        tag[st] = 0;
    }
    
    void update(int st, int l, int r, int x, int y, int val) {
        if (l >= x && r <= y) {
            t[st] += val;
            tag[st] += val;
            return;
        }
        push_down(st);
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(ls, l, mid, x, y, val);
        if (y > mid)
            update(rs, mid + 1, r, x, y, val);
        t[st] = min(t[ls], t[rs]);
    }
    
    int a[maxn], p[maxn];
    
    void solve() {
        int n;
        cin >> n;
        rep(i, 1, n)cin >> p[i];
        rep(i, 1, n)cin >> a[i];
        rep(i, 1, n)update(1, 1, n, p[i], n, a[i]);
        int ans = min(a[1], a[n]);
        rep(i, 1, n - 1) {
            update(1, 1, n, p[i], n, -a[i]);
            if (p[i] != 1)
                update(1, 1, n, 1, p[i] - 1, a[i]);
            ans = min(ans, t[1]);
        }
        cout << ans;
    }
    
    signed main() {
        start;
        while (T--)
            solve();
        return 0;
    }
    
  • 相关阅读:
    对象中属性 加锁 用:volatile 关键词修饰 而 不用 synchronized 加锁
    利用URL重写实现参数目录化
    外部联接
    快速获取表的记录数
    SQL SEVER 元年是1900年
    SQL SERVER的浮点数类型及与C#的对应关系
    接口中包含抽象类demo
    接口的实际应用demo
    多态demo2
    抽象类的实际应用demo
  • 原文地址:https://www.cnblogs.com/F-Mu/p/13138712.html
Copyright © 2011-2022 走看看