Submission #634785

#TimeUsernameProblemLanguageResultExecution timeMemory
634785SonPalembang Bridges (APIO15_bridge)C++14
8 / 100
508 ms262144 KiB
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define MAXN 200005

set < int > st;
vector < int > V;
int n,k,N;
int P[100000 + 5],S[100000 + 5], Q[100000 + 5], T[100000 + 5];
char inp[10];
LL gans = LLONG_MAX;

vector < int > MS[MAXN * 4 + 5];
vector < int > VMS[MAXN * 4 + 5], CA[MAXN * 4 + 5], CB[MAXN * 4 + 5];
vector < LL > PA[MAXN * 4 + 5], PB[MAXN * 4 + 5];

vector < int > TA[MAXN * 4 + 5], TB[MAXN * 4 + 5], VA[MAXN * 4 + 5], VB[MAXN * 4 + 5];
vector < LL > A[MAXN * 4 + 5], B[MAXN * 4 + 5];

int mut( int a ){
    if ( a < 0 ) a = a * -1;
    return a;
}

int gv( int x ){
    if ( x > 1e9 + 1 ) return V.size()-1;
    return lower_bound(V.begin(),V.end(),x) - V.begin();
}

void upd( int p, int s, int e, int x, int v ){
    MS[p].pb(v);
    if ( s == e ) return;
    int m = ( s + e) >> 1;
    if ( x <= m ) upd(p+p+1,s,m,x,v);
    else upd(p+p+2,m+1,e,x,v);
}

void process( int p ){
    st.clear();
    for ( int id : MS[p] ){
        st.insert(S[id] + T[id]);
    }
    for ( int s : st ){
        VMS[p].pb(s);
        PA[p].pb(0);
        PB[p].pb(0);
        CA[p].pb(0);
        CB[p].pb(0);
    }
    for ( int id : MS[p] ){
        int pos = lower_bound(VMS[p].begin(),VMS[p].end(),S[id] + T[id]) - VMS[p].begin();
        CA[p][pos]++;
        CB[p][pos]++;
        PA[p][pos] += S[id];
        PB[p][pos] += T[id];
    }
    for ( int i = 1; i < VMS[p].size(); i++ ){
        CA[p][i] += CA[p][i-1];
        CB[p][i] += CB[p][i-1];
        PA[p][i] += PA[p][i-1];
        PB[p][i] += PB[p][i-1];
    }

    st.clear();
    for ( int id : MS[p] ){
        st.insert(T[id]);
    }
    for ( int s : st ){
        VB[p].pb(s);
        TB[p].pb(0);
        B[p].pb(0);
    }

    for ( int id : MS[p] ){
        int pos = lower_bound(VB[p].begin(),VB[p].end(), T[id]) - VB[p].begin();
        TB[p][pos]++;
        B[p][pos] += T[id];
    }

    for ( int i = 1; i < VB[p].size(); i++ ){
        TB[p][i] += TB[p][i-1];
        B[p][i] += B[p][i-1];
    }

    st.clear();
    for ( int id : MS[p] ){
        st.insert(S[id]);
    }
    for ( int s : st ){
        VA[p].pb(s);
        TA[p].pb(0);
        A[p].pb(0);
    }

    for ( int id : MS[p] ){
        int pos = lower_bound(VA[p].begin(),VA[p].end(), S[id]) - VA[p].begin();
        TA[p][pos]++;
        A[p][pos] += S[id];
    }

    for ( int i = 1; i < VA[p].size(); i++ ){
        TA[p][i] += TA[p][i-1];
        A[p][i] += A[p][i-1];
    }
}

void build( int p, int s, int e ){
    process(p);
    if ( s == e ){
        return;
    }  
    int m = ( s + e ) >> 1;
    build(p+p+1,s,m);
    build(p+p+2,m+1,e);
}

LL rmq_b( int p, int s, int e, int r ){
    if ( s > r ) return 0;
    if ( e <= r ){
        int pos = upper_bound(VB[p].begin(),VB[p].end(), V[r]) - VB[p].begin() - 1;
        LL sum = 0;

        if ( pos >= 0 ){
            sum += V[r] * 1LL * TB[p][pos] - B[p][pos];
            sum = sum + sum;
        }

        return sum;
    }
    int m = ( s + e ) >> 1;
    return rmq_b(p+p+1,s,m,r) + rmq_b(p+p+2,m+1,e,r);
}

LL rmq_bb( int p, int s, int e, int l, int r ){
    if ( s > r || e < l ) return 0;
    if ( l <= s && e <= r ){
        int pos = upper_bound(VB[p].begin(),VB[p].end(), V[r]) - VB[p].begin();
        LL sum = 0;
        if ( pos < VB[p].size() ){
            sum += B[p].back() - (pos==0?0:B[p][pos-1]);
            sum -= 1LL * V[r] * (TB[p].back() - (pos==0?0:TB[p][pos-1]));
        }
        return sum;
    }
}

LL rmq_a( int p, int s, int e, int l ){
    if ( e < l ) return 0;
    if ( l <= s ){
        int pos = lower_bound(VA[p].begin(),VA[p].end(),V[l]) - VA[p].begin();
        LL sum = 0;
        if ( pos < VA[p].size() ){
            sum += A[p].back() - (pos == 0 ? 0 : A[p][pos-1]) - 1LL * V[l] * (TA[p].back() - (pos==0?0:TA[p][pos-1]));
            sum += sum;
        }
        return sum;
    }
    int m = ( s + e ) >> 1;
    return rmq_a(p+p+1,s,m,l) + rmq_a(p+p+2,m+1,e,l);
}

LL rmq_ab( int p, int s, int e , int l, int r ){
    if ( s > r || e < l ) return 0;
    if ( l <= s && e <= r ){
        int lim = V[l] + V[r];
        LL sum = 0;
        int pos = upper_bound(VMS[p].begin(),VMS[p].end(), lim) - VMS[p].begin() - 1;

        if ( pos >= 0 ){
            sum += PA[p][pos] - 1LL * V[l] * (CA[p][pos]);
            sum = sum + sum;
        }
        return sum;
    }
    int m = ( s + e ) / 2;
    return rmq_ab(p+p+1,s,m,l,r) + rmq_ab(p+p+2,m+1,e,l,r);
}

LL rmq_ba( int p, int s, int e, int l, int r ){
    if ( s > r || e < l ) return 0;
    if ( l <= s && e <= r ){
        int lim = V[l] + V[r];
        LL sum = 0;
        int pos = upper_bound(VMS[p].begin(),VMS[p].end(), lim) - VMS[p].begin();

        if ( pos < VMS[p].size()){
            sum += 1LL * V[r] * (CB[p].back() - (pos == 0 ? 0 : CB[p][pos-1]));
            sum -= PB[p].back() - (pos==0?0:PB[p][pos-1]);
        }
        return sum;
    } 
    int m = ( s + e ) >> 1;
    return rmq_ba(p+p+1,s,m,l,r) + rmq_ba(p+p+2,m+1,e,l,r);
}

LL solve( int p1, int p2 ){
    LL ls = rmq_b(0,0,N,p1);
    LL rs = rmq_a(0,0,N,p2);
    LL ab = rmq_ab(0,0,N,p1,p2);
    LL ba = rmq_ba(0,0,N,p1,p2) - rmq_bb(0,0,N,p1,p2);
    //printf("%lld %lld %lld %lld = %d %d\n",ls,rs,ab,ba + ba,V[p1],V[p2]);
    return ls + rs + ab + ba + ba;
}

void dnc( int l, int r, int optl, int optr ){
    if ( l > r ) return;
    int m = ( l + r ) / 2;
    LL ans = LLONG_MAX;
    int opt = -1;
    for ( int i = optl; i <= min(m-1, optr); i++ ){
        LL temp = solve(i,m);
        if ( temp < ans ) ans = temp;
    }
    if ( ans < gans ) gans = ans;
    dnc(l,m-1,optl,opt);
    dnc(m+1,r,opt,optr);
}

int main(){

    scanf("%d%d",&k,&n);
    LL ans = 1e18, sum = 0;
    for ( int i = 0; i < n; i++ ){
        scanf("%s%d",&inp,&S[i]);
        if ( inp[0] == 'A' ){
            P[i] = 0;
        } else {
            P[i] = 1;
        }

        scanf("%s%d",&inp,&T[i]);
        if ( inp[0] == 'A' ){
            Q[i] = 0;
        } else {
            Q[i] = 1;
        }
        // P[i] = 0;
        // Q[i] = 1;
        // S[i] = i;
        // T[i] = 1e9 - i;

        if ( S[i] > T[i] ) swap(S[i],T[i]);
        
        sum += T[i] - S[i];
        if ( P[i] != Q[i] ){
            st.insert(S[i]);
            st.insert(T[i]);
            sum++;
        }
    }

    st.insert(-1);
    st.insert(1e9 + 1);
    for ( int s : st ) V.pb(s);
    N = V.size()-1;

    for ( int i = 0; i < n; i++ ){
        if ( P[i] != Q[i] ){
            upd(0,0,N,gv(S[i]),i);
        }
    } 

    build(0,0,N);

    if ( k == 1 ){
        for ( int i = 0; i <= N; i++ ){
            LL temp = rmq_b(0,0,N,i) + rmq_a(0,0,N,i);
            if ( temp + sum < ans ) ans = temp + sum;
        }
    } else {
        dnc(1,N,0,N);
        ans = gans + sum;
    }
    printf("%lld\n",ans);
    return 0;
}

Compilation message (stderr)

bridge.cpp: In function 'void process(int)':
bridge.cpp:58:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   58 |     for ( int i = 1; i < VMS[p].size(); i++ ){
      |                      ~~^~~~~~~~~~~~~~~
bridge.cpp:81:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   81 |     for ( int i = 1; i < VB[p].size(); i++ ){
      |                      ~~^~~~~~~~~~~~~~
bridge.cpp:102:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  102 |     for ( int i = 1; i < VA[p].size(); i++ ){
      |                      ~~^~~~~~~~~~~~~~
bridge.cpp: In function 'long long int rmq_bb(int, int, int, int, int)':
bridge.cpp:140:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  140 |         if ( pos < VB[p].size() ){
      |              ~~~~^~~~~~~~~~~~~~
bridge.cpp: In function 'long long int rmq_a(int, int, int, int)':
bridge.cpp:153:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  153 |         if ( pos < VA[p].size() ){
      |              ~~~~^~~~~~~~~~~~~~
bridge.cpp: In function 'long long int rmq_ba(int, int, int, int, int)':
bridge.cpp:187:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  187 |         if ( pos < VMS[p].size()){
      |              ~~~~^~~~~~~~~~~~~~~
bridge.cpp: In function 'int main()':
bridge.cpp:225:17: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'char (*)[10]' [-Wformat=]
  225 |         scanf("%s%d",&inp,&S[i]);
      |                ~^    ~~~~
      |                 |    |
      |                 |    char (*)[10]
      |                 char*
bridge.cpp:232:17: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'char (*)[10]' [-Wformat=]
  232 |         scanf("%s%d",&inp,&T[i]);
      |                ~^    ~~~~
      |                 |    |
      |                 |    char (*)[10]
      |                 char*
bridge.cpp: In function 'long long int rmq_bb(int, int, int, int, int)':
bridge.cpp:146:1: warning: control reaches end of non-void function [-Wreturn-type]
  146 | }
      | ^
bridge.cpp: In function 'int main()':
bridge.cpp:222:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  222 |     scanf("%d%d",&k,&n);
      |     ~~~~~^~~~~~~~~~~~~~
bridge.cpp:225:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  225 |         scanf("%s%d",&inp,&S[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~
bridge.cpp:232:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  232 |         scanf("%s%d",&inp,&T[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...