結果

問題 No.2065 Sum of Min
ユーザー 👑 p-adicp-adic
提出日時 2022-08-29 17:33:56
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 5,238 bytes
コンパイル時間 2,034 ms
コンパイル使用メモリ 197,572 KB
実行使用メモリ 487,064 KB
最終ジャッジ日時 2024-04-24 11:33:33
合計ジャッジ時間 7,985 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 334 ms
485,120 KB
testcase_01 AC 330 ms
479,616 KB
testcase_02 AC 327 ms
479,616 KB
testcase_03 AC 330 ms
479,744 KB
testcase_04 TLE -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
using namespace std;

using ll = long long;

#define CIN( LL , A ) LL A; cin >> A 
#define FOR( VAR , INITIAL , FINAL_PLUS_ONE ) for( int VAR = INITIAL ; VAR < FINAL_PLUS_ONE ; VAR ++ ) 
#define REPEAT( HOW_MANY_TIMES ) FOR( VARIABLE_FOR_REPEAT , 0 , HOW_MANY_TIMES ) 
#define RETURN( ANSWER ) cout << ( ANSWER ) << "\n"; return 0 
#define MIN( A , B ) A < B ? A : B 

#define SET_BC					\
  ll& Ai = A[i];				\
  if( Ai <= thr ){				\
    num = i / N_lim_D_sum_d;			\
    B_val_d[B_length_d] = Ai;			\
    B_val_sum_d_num += Ai;			\
    B_ind_d[B_length_d] = i;			\
    B_ind_count_d_num++;			\
    B_length_d++;				\
  } else if( Ai < thr_plus ){			\
    C_val_d[C_length_d] = Ai;			\
    C_ind_d[C_length_d] = i;			\
    C_length_d++;				\
  }						\
						\


int main(){
  ios_base::sync_with_stdio( false );
  cin.tie( nullptr );
  constexpr const int N_lim = 100001;
  // constexpr const int N_lim_dummy = N_lim;
  // 嘘解法チェック
  // constexpr const int N_lim_dummy = 10001;
  constexpr const int N_lim_dummy = 1001;
  CIN( int , N );
  CIN( int , Q );
  ll A[N_lim];
  N++;
  FOR( i , 1 , N ){
    cin >> A[i];
  }
  // D_val は ll[D_val_plus][N_lim] たちが メモリオーバーしない程度に大きい値
  constexpr const int D_val = 400;
  constexpr const int D_val_plus = D_val + 1;
  // D_sum は sqrt( N_lim ) 付近
  constexpr const int D_sum = 316;
  constexpr const int D_sum_plus = D_sum + 1;
  ll B_val[D_val_plus][N_lim] = {};
  ll B_val_sum[D_val_plus][D_sum_plus] = {};
  int B_ind[D_val_plus][N_lim] = {};
  int B_ind_count[D_val_plus][D_sum_plus] = {};
  int B_length[D_val_plus] = {};
  ll C_val[D_val_plus][N_lim_dummy] = {};
  int C_ind[D_val_plus][N_lim_dummy] = {};
  int C_length[D_val_plus] = {};
  int N_lim_D_sum[D_val_plus];
  ll thr;
  ll thr_plus;
  int num;
  int i_start;
  int i_lim;
  constexpr const ll A_div = 1000000001 / D_val;
  FOR( d , 0 , D_val_plus ){
    thr = A_div * d;
    thr_plus = thr + A_div;
    ll ( &B_val_d )[N_lim] = B_val[d];
    ll ( &B_val_sum_d )[D_sum_plus] = B_val_sum[d];
    int ( &B_ind_d )[N_lim] = B_ind[d];
    int ( &B_ind_count_d )[D_sum_plus] = B_ind_count[d];
    int& B_length_d = B_length[d];
    ll ( &C_val_d )[N_lim_dummy] = C_val[d];
    int ( &C_ind_d )[N_lim_dummy] = C_ind[d];
    int& C_length_d = C_length[d];
    int& N_lim_D_sum_d = N_lim_D_sum[d];
    N_lim_D_sum_d = N / D_sum_plus + ( N % D_sum_plus == 0 ? 0 : 1 );
    {
      i_start = 1;
      i_lim = N_lim_D_sum_d;
      ll& B_val_sum_d_num = B_val_sum_d[0];
      int& B_ind_count_d_num = B_ind_count_d[0];
      FOR( i , i_start , i_lim ){
	SET_BC;
      }
    }
    FOR( num , 1 , D_sum ){
      i_start = i_lim;
      i_lim += N_lim_D_sum_d;
      ll& B_val_sum_d_num = B_val_sum_d[num];
      int& B_ind_count_d_num = B_ind_count_d[num];
      FOR( i , i_start , i_lim ){
	SET_BC;
      }
    }
    {
      ll& B_val_sum_d_num = B_val_sum_d[D_sum];
      int& B_ind_count_d_num = B_ind_count_d[D_sum];
      FOR( i , i_lim , N ){
	SET_BC;
      }
    }
  }
  int L;
  int R;
  ll X;
  ll sum;
  int count;
  int d;
  int num0;
  int num1;
  int j_start;
  int J;
  int L_plus;
  int R_minus;
  REPEAT( Q ){
    cin >> L;
    cin >> R;
    cin >> X;
    sum = 0;
    count = 0;
    d = X / A_div;
    int& N_lim_D_sum_d = N_lim_D_sum[d];
    num0 = L / N_lim_D_sum_d + ( L % N_lim_D_sum_d == 0 ? 0 : 1 );
    num1 = R / N_lim_D_sum_d;
    ll ( &B_val_d )[N_lim] = B_val[d];
    int ( &B_ind_d )[N_lim] = B_ind[d];
    int& B_length_d = B_length[d];
    j_start = -1;
    J = B_length_d / 2;
    while( J != 0 ){
      while( j_start + J < B_length_d ? B_ind_d[j_start + J] < L : false ){
	j_start += J;
      }
      J /= 2;
    }
    j_start++;
    if( num0 < num1 ){
      ll ( &B_val_sum_d )[D_sum_plus] = B_val_sum[d];
      int ( &B_ind_count_d )[D_sum_plus] = B_ind_count[d];
      L_plus = num0 * N_lim_D_sum_d;
      R_minus = num1 * N_lim_D_sum_d;
      FOR( j , j_start , B_length_d ){
	if( B_ind_d[j] < L_plus ){
	  sum += B_val_d[j];
	  count++;
	} else {
	  j_start = j - 1;
	  j = B_length_d;
	}
      }
      FOR( num , num0 , num1 ){
	sum += B_val_sum_d[num];
	count += B_ind_count_d[num];
      }
      J = B_length_d / 2;
      while( J != 0 ){
	while( j_start + J < B_length_d ? B_ind_d[j_start + J] < R_minus : false ){
	  j_start += J;
	}
	J /= 2;
      }
      j_start++;
      FOR( j , j_start , B_length_d ){
	if( B_ind_d[j] <= R ){
	  sum += B_val_d[j];
	  count++;
	}
      }
    } else {
      FOR( j , j_start , B_length_d ){
	if( B_ind_d[j] <= R ){
	  sum += B_val_d[j];
	  count++;
	} else {
	  j = B_length_d;
	}
      }
    }
    ll ( &C_val_d )[N_lim_dummy] = C_val[d];
    int ( &C_ind_d )[N_lim_dummy] = C_ind[d];
    int& C_length_d = C_length[d];
    j_start = -1;
    J = C_length_d / 2;
    while( J != 0 ){
      while( j_start + J < C_length_d ? C_ind_d[j_start + J] < L : false ){
	j_start += J;
      }
      J /= 2;
    }
    j_start++;
    FOR( j , j_start , C_length_d ){
      if( C_ind_d[j] <= R ){
	ll& C_val_dj = C_val_d[j];
	sum += MIN( X , C_val_dj );
	count++;
      } else {
	j = C_length_d;
      }
    }
    sum += ( R - L + 1 - count ) * X;
    cout << sum << "\n";
  }
  return 0;
}
0