萌新二分队列全wa求调!
查看原帖
萌新二分队列全wa求调!
824941
bsjsaikou10楼主2024/7/31 21:22
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#include<stdlib.h>
#include<numeric>
#include<unordered_set>
#define int long long
using namespace std;
const int MAXN = 35e3 + 3;
const int MAXK = 55 + 4;
const int MOD = 1e9 + 7;
int n,k;
int a[MAXN],f[MAXN][MAXK];
int cnt[MAXN];
int L = 1,R = 0;
int res = 0;
void add(int x){
    res += !cnt[x]++;
}
void del(int x){
    res -= !--cnt[x];
}
int val(int l,int r){
    int t = l,t2 = r;
    r = max(t,t2);
    l = min(t,t2);
    while(L > l){
        add(a[--L]);
    }
    while(R < r){
        add(a[++R]);
    }
    while(R > r){
        del(a[R--]);
    }
    while(L < l){
        del(a[L++]);
    }
    return res;
}
int q[MAXN];
int lt[MAXN],rt[MAXN];
void work(int j){
    int l = 1,r = 0;
    //dq.clear();
    for(int i = 0; i <= n + 1; i++){
        lt[i] = 0;
        rt[i] = 0;
    }
    q[++r] = 1;
    lt[1] = 1;
    rt[1] = n;
    for(int i = 1; i <= n; i++){
        while(l <= r && rt[q[l]] < i){
            l++;
        }
        f[i][j] = f[q[l] - 1][j - 1] + val(q[l],i);
        lt[q[l]] = i;
        while(l <= r && f[q[r] - 1][j - 1] + val(q[r],lt[q[r]]) < f[i - 1][j - 1] + val(i,lt[q[r]])){
            r--;
        }
        if(l > r){
            q[++r] = i;
            lt[i] = i + 1;
            rt[i] = n;
        }
        else if(f[q[r] - 1][j - 1] + val(q[r],rt[q[r]]) > f[i - 1][j - 1] + val(i,rt[q[r]])){
            if(rt[q[r]] < n){
                q[++r] = i;
                lt[i] = rt[q[r]] + 1;
                rt[i] = n;
            }
        }
        else{
            int ll = lt[q[r]];
            int rr = rt[q[r]];
            int x = 0;
            while(ll <= rr){
                int mid = (ll + rr) >> 1;
                if(f[i - 1][j - 1] + val(i,mid) > f[q[r] - 1][j - 1] + val(q[r],mid)){
                    x = mid;
                    rr = mid - 1;
                }
                else{
                    ll = mid + 1;
                }
            }
            rt[q[r]] = x - 1;
            q[++r] = i;
            lt[i] = x;
            rt[i] = n;
        }
    }
}
int opt[MAXK][MAXN];
void work2(){
    for(int i = 1; i <= n; i++){
        opt[k + 1][i] = i;
    }
    for(int i = 1; i <= k; i++){
        opt[i][0] = 1;
    }
    for(int i = 1; i <= n; i++){
        for(int j = k; j >= 1; j--){
            for(int p = opt[j][i - 1]; p <= opt[j + 1][i]; p++){
                int temp = f[p - 1][j - 1] + val(p,i);
                if(temp > f[i][j]){
                    f[i][j] = temp;
                    opt[j][i] = p;
                }
            }
        }
    }
    cout << f[n][k] << endl;
}
void solve(){
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    for(int i = 1; i <= k; i++){
        work(i);
    }
    cout << f[n][k] << endl;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    T = 1;
    while(T--){
        solve();
    }
}


2024/7/31 21:22
加载中...