Submission #692067


Source Code Expand

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define MOD (ll)(1e9+7)
#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

// Hu-Tucker algorithm
// 間に葉のない二接点の組み合わせの内、和が最小のものを選ぶ
// 右側の接点を削除し、左側の接点に値を追加する
// 左側の接点が葉であった場合それを内点に変更する
// これを実装すれば良い

// 葉→葉という範囲を全て meldable heap で持つ

// 葉 (A) と 葉 (B) の併合の場合
// 葉 (C) - 葉 (A) - 葉 (B) - 葉(D)
// → 葉 (C) - 接点 (AB) - 葉 (D)
// CA, AB, BD 全て併合

// 葉 (A) と 接点 (B) の併合の場合
// 葉 (C) - 葉 (A) - 接点 (B) - 葉 (D)
// → 葉(C) - 接点 (AB) - 葉 (D)
// CA, AD 併合

// 接点 (A) と 接点 (B) の併合の場合
// 葉 (C) - 接点 (A) - 接点 (B) - 葉 (D)
// → 葉 (C) - 接点 (AB) - 葉 (D)
// 変化なし

int n;
int a[125252];

struct seq_data{
  // 最小和、最小ペア左、最小ペア右、列ID
  int sum,left,right,id;
  seq_data(int s,int l,int r,int i):sum(s),left(l),right(r),id(i){}
};
bool operator<(const seq_data &a, const seq_data &b){
  if(a.sum!=b.sum)return a.sum<b.sum;
  if(a.left!=b.left)return a.left<b.left;
  if(a.right!=b.right)return a.right<b.right;
  return a.id<b.id;
}
// queue of pii<minsum,seq_id>
set<seq_data> master_queue;

// sequence sets
multiset<pii> sequence[125252];
// 列左端、列右端
int seq_left[125252], seq_right[125252];
// 前列、後列
int seq_prev[125252], seq_succ[125252];

int getSmallestSum(int id){
  int res = 0;
  multiset<pii>::iterator iter = sequence[id].begin();
  res += iter->first;
  iter++;
  res += iter->first;
  return res;
}

pii getSmallestPair(int id){
  pii ret;
  multiset<pii>::iterator iter = sequence[id].begin();
  ret.first = iter->second;
  iter++;
  ret.second = iter->second;
  if(ret.first > ret.second) swap(ret.first,ret.second);
  return ret;
}

void master_push(int id){
  pii s_p = getSmallestPair(id);
  master_queue.insert(seq_data(
    getSmallestSum(id), s_p.first, s_p.second, id
  ));
}

void master_erase(int id){
  pii s_p = getSmallestPair(id);
  master_queue.erase(seq_data(
    getSmallestSum(id), s_p.first, s_p.second, id
  ));
}

ll hu_tucker(){
  ll ans = 0;
  REP(i,n-1){
    seq_left[i] = i;
    seq_right[i] = i+1;
    seq_prev[i] = i-1;
    seq_succ[i] = i+1;
    sequence[i].insert(pii(a[i],i));
    sequence[i].insert(pii(a[i+1],i+1));
    master_push(i);
  }
  REP(_,n-3){
    seq_data data = *master_queue.begin();
    master_queue.erase(master_queue.begin());
    int sum = data.sum;
    int x = data.left;
    int y = data.right;
    int id = data.id;
    ans += sum;
    // merge
    if(x == seq_left[id] && y == seq_right[id]){
      // merge 3 seq
      int aa = seq_prev[id], b = id, c = seq_succ[id];
      master_erase(aa);
      master_erase(b);
      master_erase(c);
      int leflef = seq_left[aa];
      int rigrig = seq_right[c];
      int prepre = seq_prev[aa], sucsuc = seq_succ[c];
      pii p = pii(a[x],x), q = pii(a[y],y);
      sequence[aa].erase(sequence[aa].find(p));
      sequence[b].erase(sequence[b].find(p));
      sequence[b].erase(sequence[b].find(q));
      sequence[c].erase(sequence[c].find(q));
      a[x] += a[y];
      p = pii(a[x],x);
      if(sequence[b].size()<sequence[c].size()) swap(b,c);
      if(sequence[aa].size()<sequence[b].size()) swap(aa,b);
      multiset<pii>::iterator iter;
      iter = sequence[b].begin();
      while(iter!=sequence[b].end()){
        sequence[aa].insert(*iter);
        ++iter;
      }
      sequence[b].clear();
      iter = sequence[c].begin();
      while(iter!=sequence[c].end()){
        sequence[aa].insert(*iter);
        ++iter;
      }
      sequence[c].clear();
      sequence[aa].insert(p);
      seq_left[aa] = leflef;
      seq_right[aa] = rigrig;
      seq_prev[aa] = prepre;
      seq_succ[aa] = sucsuc;
      if(prepre>=0) seq_succ[prepre] = aa;
      if(sucsuc<n-1) seq_prev[sucsuc] = aa;
      master_push(aa);
    }else if(x == seq_left[id]){
      // merge 2 seq
      int aa = seq_prev[id], b = id;
      master_erase(aa);
      master_erase(b);
      int leflef = seq_left[aa];
      int rigrig = seq_right[b];
      int prepre = seq_prev[aa], sucsuc = seq_succ[b];
      pii p = pii(a[x],x), q = pii(a[y],y);
      sequence[aa].erase(sequence[aa].find(p));
      sequence[b].erase(sequence[b].find(p));
      sequence[b].erase(sequence[b].find(q));
      a[x] += a[y];
      p = pii(a[x],x);
      if(sequence[aa].size()<sequence[b].size()) swap(aa,b);
      multiset<pii>::iterator iter;
      iter = sequence[b].begin();
      while(iter!=sequence[b].end()){
        sequence[aa].insert(*iter);
        ++iter;
      }
      sequence[b].clear();
      sequence[aa].insert(p);
      seq_left[aa] = leflef;
      seq_right[aa] = rigrig;
      seq_prev[aa] = prepre;
      seq_succ[aa] = sucsuc;
      if(prepre>=0) seq_succ[prepre] = aa;
      if(sucsuc<n-1) seq_prev[sucsuc] = aa;
      master_push(aa);
    }else if(y == seq_right[id]){
      // merge 2 seq
      int aa = id, b = seq_succ[id];
      master_erase(aa);
      master_erase(b);
      int leflef = seq_left[aa];
      int rigrig = seq_right[b];
      int prepre = seq_prev[aa], sucsuc = seq_succ[b];
      pii p = pii(a[x],x), q = pii(a[y],y);
      sequence[aa].erase(sequence[aa].find(p));
      sequence[aa].erase(sequence[aa].find(q));
      sequence[b].erase(sequence[b].find(q));
      a[x] += a[y];
      p = pii(a[x],x);
      if(sequence[aa].size()<sequence[b].size()) swap(aa,b);
      multiset<pii>::iterator iter;
      iter = sequence[b].begin();
      while(iter!=sequence[b].end()){
        sequence[aa].insert(*iter);
        ++iter;
      }
      sequence[b].clear();
      sequence[aa].insert(p);
      seq_left[aa] = leflef;
      seq_right[aa] = rigrig;
      seq_prev[aa] = prepre;
      seq_succ[aa] = sucsuc;
      if(prepre>=0) seq_succ[prepre] = aa;
      if(sucsuc<n-1) seq_prev[sucsuc] = aa;
      master_push(aa);
    }else{
      // no merge only delete
      master_erase(id);
      pii p = pii(a[x],x), q = pii(a[y],y);
      sequence[id].erase(sequence[id].find(p));
      sequence[id].erase(sequence[id].find(q));
      a[x] += a[y];
      p = pii(a[x],x);
      sequence[id].insert(p);
      master_push(id);
    }
  }
  return ans;
}

int main(){
  scanf("%d",&n);
  REP(i,n)scanf("%lld",a+i+1);
  a[0] = 1e9;
  a[n+1] = 1e9;
  n += 2;
  ll ans = hu_tucker();
  printf("%lld\n",ans);
  return 0;
}

Submission Info

Submission Time
Task C - 最適二分探索木
User rickytheta
Language C++14 (GCC 5.4.1)
Score 101
Code Size 7185 Byte
Status AC
Exec Time 332 ms
Memory 23680 KB

Compile Error

./Main.cpp: In function ‘int main()’:
./Main.cpp:238:29: warning: format ‘%lld’ expects argument of type ‘long long int*’, but argument 2 has type ‘int*’ [-Wformat=]
   REP(i,n)scanf("%lld",a+i+1);
                             ^
./Main.cpp:237:17: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&n);
                 ^
./Main.cpp:238:30: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
   REP(i,n)scanf("%lld",a+i+1);
                              ^

Judge Result

Set Name Sample Dataset1 Dataset2 Dataset3
Score / Max Score 0 / 0 50 / 50 50 / 50 1 / 1
Status
AC × 1
AC × 31
AC × 61
AC × 96
Set Name Test Cases
Sample 00_sample_01.txt
Dataset1 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt
Dataset2 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 02_00.txt, 02_01.txt, 02_02.txt, 02_03.txt, 02_04.txt, 02_05.txt, 02_06.txt, 02_07.txt, 02_08.txt, 02_09.txt, 02_10.txt, 02_11.txt, 02_12.txt, 02_13.txt, 02_14.txt, 02_15.txt, 02_16.txt, 02_17.txt, 02_18.txt, 02_19.txt, 02_20.txt, 02_21.txt, 02_22.txt, 02_23.txt, 02_24.txt, 02_25.txt, 02_26.txt, 02_27.txt, 02_28.txt, 02_29.txt
Dataset3 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 02_00.txt, 02_01.txt, 02_02.txt, 02_03.txt, 02_04.txt, 02_05.txt, 02_06.txt, 02_07.txt, 02_08.txt, 02_09.txt, 02_10.txt, 02_11.txt, 02_12.txt, 02_13.txt, 02_14.txt, 02_15.txt, 02_16.txt, 02_17.txt, 02_18.txt, 02_19.txt, 02_20.txt, 02_21.txt, 02_22.txt, 02_23.txt, 02_24.txt, 02_25.txt, 02_26.txt, 02_27.txt, 02_28.txt, 02_29.txt, 03_00.txt, 03_01.txt, 03_02.txt, 03_03.txt, 03_04.txt, 03_05.txt, 03_06.txt, 03_07.txt, 03_08.txt, 03_09.txt, 03_10.txt, 03_11.txt, 03_12.txt, 03_13.txt, 03_14.txt, 03_15.txt, 03_16.txt, 03_17.txt, 03_18.txt, 03_19.txt, 03_20.txt, 03_21.txt, 03_22.txt, 03_23.txt, 03_24.txt, 03_25.txt, 03_26.txt, 03_27.txt, 03_28.txt, 03_29.txt, 03_30.txt, 03_31.txt, 03_32.txt, 03_33.txt, 03_34.txt
Case Name Status Exec Time Memory
00_sample_01.txt AC 15 ms 6144 KB
01_00.txt AC 15 ms 6144 KB
01_01.txt AC 15 ms 6144 KB
01_02.txt AC 15 ms 6144 KB
01_03.txt AC 15 ms 6144 KB
01_04.txt AC 15 ms 6144 KB
01_05.txt AC 14 ms 6144 KB
01_06.txt AC 14 ms 6144 KB
01_07.txt AC 15 ms 6144 KB
01_08.txt AC 14 ms 6144 KB
01_09.txt AC 14 ms 6144 KB
01_10.txt AC 15 ms 6144 KB
01_11.txt AC 16 ms 6144 KB
01_12.txt AC 14 ms 6144 KB
01_13.txt AC 14 ms 6144 KB
01_14.txt AC 14 ms 6144 KB
01_15.txt AC 14 ms 6144 KB
01_16.txt AC 14 ms 6144 KB
01_17.txt AC 14 ms 6144 KB
01_18.txt AC 15 ms 6144 KB
01_19.txt AC 15 ms 6144 KB
01_20.txt AC 16 ms 6144 KB
01_21.txt AC 14 ms 6144 KB
01_22.txt AC 14 ms 6144 KB
01_23.txt AC 14 ms 6144 KB
01_24.txt AC 14 ms 6144 KB
01_25.txt AC 14 ms 6144 KB
01_26.txt AC 16 ms 6144 KB
01_27.txt AC 14 ms 6144 KB
01_28.txt AC 14 ms 6144 KB
01_29.txt AC 14 ms 6144 KB
02_00.txt AC 20 ms 6656 KB
02_01.txt AC 21 ms 6656 KB
02_02.txt AC 20 ms 6656 KB
02_03.txt AC 22 ms 6656 KB
02_04.txt AC 20 ms 6656 KB
02_05.txt AC 21 ms 6656 KB
02_06.txt AC 20 ms 6656 KB
02_07.txt AC 20 ms 6656 KB
02_08.txt AC 22 ms 6656 KB
02_09.txt AC 20 ms 6656 KB
02_10.txt AC 20 ms 6656 KB
02_11.txt AC 22 ms 6656 KB
02_12.txt AC 20 ms 6656 KB
02_13.txt AC 20 ms 6656 KB
02_14.txt AC 22 ms 6656 KB
02_15.txt AC 22 ms 6656 KB
02_16.txt AC 22 ms 6656 KB
02_17.txt AC 21 ms 6656 KB
02_18.txt AC 20 ms 6656 KB
02_19.txt AC 20 ms 6656 KB
02_20.txt AC 20 ms 6656 KB
02_21.txt AC 22 ms 6656 KB
02_22.txt AC 21 ms 6656 KB
02_23.txt AC 22 ms 6656 KB
02_24.txt AC 21 ms 6656 KB
02_25.txt AC 22 ms 6656 KB
02_26.txt AC 22 ms 6656 KB
02_27.txt AC 20 ms 6656 KB
02_28.txt AC 20 ms 6656 KB
02_29.txt AC 21 ms 6656 KB
03_00.txt AC 313 ms 23680 KB
03_01.txt AC 314 ms 23680 KB
03_02.txt AC 313 ms 23680 KB
03_03.txt AC 318 ms 23680 KB
03_04.txt AC 313 ms 23680 KB
03_05.txt AC 235 ms 23680 KB
03_06.txt AC 259 ms 23680 KB
03_07.txt AC 281 ms 23680 KB
03_08.txt AC 287 ms 23680 KB
03_09.txt AC 287 ms 23680 KB
03_10.txt AC 272 ms 23680 KB
03_11.txt AC 274 ms 23680 KB
03_12.txt AC 291 ms 23680 KB
03_13.txt AC 290 ms 23680 KB
03_14.txt AC 297 ms 23680 KB
03_15.txt AC 297 ms 23680 KB
03_16.txt AC 293 ms 23680 KB
03_17.txt AC 304 ms 23680 KB
03_18.txt AC 281 ms 23680 KB
03_19.txt AC 300 ms 23680 KB
03_20.txt AC 304 ms 23680 KB
03_21.txt AC 311 ms 23680 KB
03_22.txt AC 297 ms 23680 KB
03_23.txt AC 328 ms 23680 KB
03_24.txt AC 305 ms 23680 KB
03_25.txt AC 316 ms 23680 KB
03_26.txt AC 312 ms 23680 KB
03_27.txt AC 311 ms 23680 KB
03_28.txt AC 311 ms 23680 KB
03_29.txt AC 332 ms 23680 KB
03_30.txt AC 327 ms 23680 KB
03_31.txt AC 320 ms 23680 KB
03_32.txt AC 320 ms 23680 KB
03_33.txt AC 321 ms 23680 KB
03_34.txt AC 314 ms 23680 KB