// #pragma GCC optimize("Ofast") #include using namespace std; // #include // using namespace atcoder; using ll = long long; using vecint = std::vector; using vecll = std::vector; using vecstr = std::vector; using vecbool = std::vector; using vecdou = std::vector; using vecpl = std::vector>; using vec2d = std::vector; using pl = pair; using pint = pair; #define rep(i,n) for (int i = 0; i < (int)(n); i++) #define rep1(i,n) for (int i = 1; i <= (int)(n); i++) #define all(a) (a).begin(), (a).end() #define INF 1000000000 #define inr(l,x,r) ((l) <= (x) && (x) < (r)) class TimeKeeperDouble { private: std::chrono::high_resolution_clock::time_point start_time_; double time_threshold_; double now_time_ = 0; public: // 時間制限をミリ秒単位で指定してインスタンスをつくる。 TimeKeeperDouble(const double time_threshold) : start_time_(std::chrono::high_resolution_clock::now()), time_threshold_(time_threshold) {} // 経過時間をnow_time_に格納する。 void setNowTime() { auto diff = std::chrono::high_resolution_clock::now() - this->start_time_; this->now_time_ = std::chrono::duration_cast(diff).count() * 1e-3; // ms } void changeTimeThreshold(const double time_threshold) { this->time_threshold_ = time_threshold; } // 経過時間をnow_time_に取得する。 double getNowTime() const { return this->now_time_; } // インスタンス生成した時から指定した時間制限を超過したか判定する。 bool isTimeOver() const { return now_time_ >= time_threshold_; } }; class Random { public: std::mt19937 mt_; // シード0でメルセンヌツイスターの乱数生成器を初期化 // 0以上1.0未満の実数の範囲の乱数生成 uniform_real_distribution dd_{0, 1.0}; // seedを指定して初期化 Random(const int seed = 0) : mt_(std::mt19937(seed)) {} // 0以上m未満の整数の範囲の乱数 inline int nextInt(const int m) { uniform_int_distribution di(0, m - 1); return di(mt_); } // 0以上1.0未満の実数の範囲の乱数 inline double nextDouble() { return dd_(mt_); } // 0以上1.0未満の実数の範囲の乱数のlog。焼きなまし法で使いやすい。 inline double nextLog() { return log(dd_(mt_)); } }; Random rnd(0); int mod = 100000000; int n=50; vector a(50,vecint(50)); int dist(int x,int y) { x%=mod; y%=mod; return min(abs(x-y),mod-abs(x-y)); } void input() { cin>>n; rep(i,n) rep(j,i+1) cin>>a[i][j]; } void solve(); int main() { input(); solve(); } void make_tower(vector> &ans){ for(int i=n-2;i>=0;i--){ for(int j=0;j<=i;j++){ ans[i][j] = ans[i+1][j] + ans[i+1][j+1]; if(ans[i][j]>=mod) ans[i][j] -= mod; } } } void solve(){ TimeKeeperDouble tkd(1900); vector> ans(n,vector(n,0)); ans[n-1] = a[n-1]; make_tower(ans); double T_first = 60.0, T_last = 0.01; double T = T_first; // int first_diff = 0; vector> diff(n, vector(n,0)); queue que; int d; while (!tkd.isTimeOver()) { int i = rnd.nextInt(n); if(rnd.nextInt(2)){ diff[n-1][i]++; que.push({n-1,i}); d=0; while(!que.empty()){ auto [x,y] = que.front(); que.pop(); d += dist(a[x][y], ans[x][y]+diff[x][y]) - dist(a[x][y], ans[x][y]); if(x>0){ if(y=mod) ans[n-1][i] -= mod; make_tower(ans); } }else{ diff[n-1][i]--; que.push({n-1,i}); d=0; while(!que.empty()){ auto [x,y] = que.front(); que.pop(); d += dist(a[x][y], ans[x][y]+diff[x][y]) - dist(a[x][y], ans[x][y]); if(x>0){ if(y