Codeforces Round #783

D. Optimal Partition

考虑到动态规划有:$dp_i=max\{dp_i,dp_j+i-j\}$其中$(j < i,sum[j] \leqslant sum[i])$,所以我们可以用树状数组维护最大值$dp_i-i$

#include <algorithm>
#include <bitset>
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <cmath>
#include <stack>
#include <set>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define LL long long
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "w", stdout)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define sqr(x) (x) * (x)
#define pr1(x) printf("Case %d: ",x)
#define pn1(x) printf("Case %d:\n",x)
#define pr2(x) printf("Case #%d: ",x)
#define pn2(x) printf("Case #%d:\n",x)
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define sz(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

const int max_n=500005, inf=10000000;
int t, n, a[max_n], dp[max_n], ord[max_n];
long long pref[max_n];


// Fenwick tree with prefix maximum

struct BIT
{
    int ff[(int)5e5+9];
    void build(){
        for(int i=1;i<=n;++i)ff[i]=-0x3f3f3f3f;
    }
    void add(int p,int v){
        while(p<=n)ff[p]=max(ff[p],v),p+=lowbit(p);
    }
    int query(int p){
        int res=-0x3f3f3f3f;
        while(p)res=max(res,ff[p]),p-=lowbit(p);
        return res;
    }
}b;


int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
   // IN;OUT;
    cin >> t;


    while (t--) {
        cin >> n;
        vector<pair<long long, int> > v;
        for (int i=1; i<=n; i++) {
            dp[i]=0;
            cin >> a[i];
            pref[i]=pref[i-1]+a[i];
            v.push_back({pref[i], -i});
        }
        sort(v.begin(), v.end());
        for (int i=0; i<n; i++) {
            ord[-v[i].second]=i+1;
        }
        // smaller prefix sum, smaller ord[i]
        // if j<i they have equal prefix sums, than ord[i]<ord[j], this way we cannot count [j+1, ... i] as a winning segment


        b.build();

        for (int i=1; i<=n; i++) {
            dp[i]=(dp[i-1]+(a[i]<0 ? -1 : a[i]>0 ? 1 : 0));
            // The last segment is 1 long.

            dp[i]=max(dp[i], b.query(ord[i])+i);
            //cerr<<ord[i]+i<<"__f-q\n";
            if (pref[i]>0) dp[i]=i;
            // Segment [1, ... i] is winning, so dp[i]=i;

            b.add(ord[i], dp[i]-i);
            //cerr<<ord[i]<<"::"<<dp[i]-i<<"__f-ad\n";
            //cerr<<"---------------------------\n";
        }
        cout << dp[n] << "\n";

    }
    return 0;
}


/*
 * ┌───┐┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐  ┌──┐  ┌──┐  ┌──┐
 * │╠╣1││Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  │┌┐│  │┌┐│  │┌┐│
 * ├───┤└───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └└┘┘  └└┘┘  └└┘┘
 * │╠╣2│┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
 * └───┘│~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
 * ┌───┐├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
 * │╠╣3││ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
 * ├───┤├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
 * │╠╣4││ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
 * └───┘├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
 * ┌───┐│ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
 * │╠╣5│├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
 * ├───┤│ Ctrl│ Win│ Alt│         Space         │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
 * │╠╣6│└─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 * └───┘
 */
上一篇
下一篇