Cod sursa(job #3285774)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 13 martie 2025 14:24:32
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.59 kb
#include <stdio.h>

static inline long long min(const long long& a, const long long& b) {
    return (a <= b ? a : b);
}

static inline long long max(const long long& a, const long long& b) {
    return (a >= b ? a : b);
}


#pragma GCC target("avx2,fma")
#pragma GCC optimize("Ofast,unroll-loops")
    
FILE *fin;
 
int poz, valBuff;
static char buff[ ( 1 << 13 ) ];
static inline char nextChar() {
    if( poz == valBuff ) {
        fread( buff, 1, valBuff, fin );
        poz = 0;
    }
 
    return buff[ poz++ ];
}
 
static bool f[ 100 ];
static inline int readInt() {
    int rez = 0;
    int ch;
 
    while( !f[ ch = nextChar() ] );
    do
        rez = rez * 10 + ch - '0';
    while( f[ ch = nextChar() ] );
 
    return rez;
}
 
/////////////////////////////////////////////////////////////////////////////////////////////
#define MAX 100000

struct Andrei{
    long long a, b;
};

const long long INF = 1e17 + 69;
const int NMAX = 1e5 + 2;
const int KMAX = 12;

#include <algorithm>

long long VV[NMAX];
long long dp[KMAX][NMAX];
Andrei sum[NMAX];
Andrei v[NMAX];
int n, K;

static inline long long cost(const int& L, const int& R) {
    return max(sum[R].a - sum[L].a, sum[R].b - sum[L].b);
}

void divide(int left, int right, const int& A, const int& B, const int& k) {
    if(left > right)
        return;

    int med = (left + right) >> 1;

    int poz = A;
    int L = (n <= 1000 ? max(A - 100, 1) : A);
    int R = (n <= 1000 ? min(B + 100, med - 1) : min(B, med - 1));
    for(int i = L; i <= R; i++)
        if(dp[k][med] > dp[k - 1][i] + cost(i, med)) {
            dp[k][med] = dp[k - 1][i] + cost(i, med);
            poz = i;
        }
    if(left != right) {
        divide(left, med, A, poz, k);
        divide(med + 1, right, poz, B, k);
    }
}

signed main() 
{
    f[ '0' ] = f[ '1' ] = f[ '2' ] = f[ '3' ] = f[ '4' ] = 1;
    f[ '5' ] = f[ '6' ] = f[ '7' ] = f[ '8' ] = f[ '9' ] = 1;
    valBuff = sizeof( buff );

    FILE *fin = fopen("bisuma.in", "r");
    fread( buff, 1, valBuff, fin );
    // fscanf(fin, "%d %d", &n, &K);
    n = readInt();
    K = readInt();

    for (int i = 1; i <= n; i++) {
        // fscanf(fin, "%lld", &v[i].a);
        v[i].a = (long long)readInt();
        sum[i].a = v[i].a + sum[i - 1].a;
    }
    for (int i = 1; i <= n; i++) {
        // fscanf(fin, "%lld", &v[i].b);
        v[i].b = (long long)readInt();
        sum[i].b = v[i].b + sum[i - 1].b;
    }
    
    fclose(fin);

    for(int j = 0; j <= K; j++)
        for(int i = 0; i <= n; i++)
            dp[j][i] = INF;
    
    dp[0][0] = 0;

    for(int i = 1; i <= n; i++)
        dp[1][i] = cost(0, i);

    for(int k = 2; k <= K; k++)
        divide(1, n, 1, n, k);

    // for(int i = 1; i <= K; i++, printf("\n"))
    //     for(int j = 1; j <= n; j++)
    //         printf("%d ", dp[i][j]);

    FILE *fout = fopen("bisuma.out", "w");
    fprintf(fout, "%lld\n", dp[K][n]);
}

/*
dp[i][k] = sum min cu primele i si k bucket
dp[i][k] = dp[j][k - 1] + max(Sa, Sb);  

# ideea I

am calculat pentru k - 1

dp[k - 1] = {x1, x2, x3, x4, x5, x6};

dp[k]     = min{dp[k - 1] + max{Sa, Sb}};

                    Sa[r] - Sa[l]         >=          Sb[r] - Sb[l];

                    Sa[r] - sb[r]         >=          sa[l] - sb[l];

dp[r][k] - S[r] =  dp[l][k - 1] - Sa[l]   |    dp[l][k - 1] - Sb[l]

 x x x  x  x Sa[r] - Sb[r] x x  x  x x

 dp[i][k] = min(sa[i] + besta[j], j <= sa[i] - sb[i],
                sb[i] + bestb[j], j >= sa[i] - sb[i] )

aint[nod] = max{suma A, suma B} + dp[k - 1];

b - a
sum(a) + probl(|b - a|)

# ideea II

DIVIDE

X X X X X X X | X X X  X  X  X  X 
1 2 3 4 5 6 7 | 8 9 10 11 12 13 14
        Y     Y Y Y  Y | Y  Y  Y
*/