結果
問題 |
No.5021 Addition Pyramid
|
ユーザー |
![]() |
提出日時 | 2025-02-25 22:59:27 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,784 ms / 2,000 ms |
コード長 | 5,572 bytes |
コンパイル時間 | 4,969 ms |
コンパイル使用メモリ | 308,440 KB |
実行使用メモリ | 6,820 KB |
スコア | 10,679,036 |
最終ジャッジ日時 | 2025-02-25 23:02:01 |
合計ジャッジ時間 | 97,758 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
#include<bits/stdc++.h> //#include <atcoder/all> #pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") using namespace std; //using namespace atcoder; typedef long long ll; typedef unsigned long long ull; #define rep(i,N) for(int i=0;i<(N);++i) #define rrep(i,N) for(int i=(N)-1;i>=0;--i) #define all(A) A.begin(),A.end() using vvi = vector<vector<int>>; using P = pair<int,int>; template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; } template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; } template<class T=bool> void YesNo(T flg){ cout << (flg? "Yes\n" : "No\n"); } //時間管理 const double TimeLimit=1780; std::chrono::system_clock::time_point start; std::chrono::system_clock::time_point finish; inline void TimerStart(){ start=finish=chrono::system_clock::now(); } inline void TimerUpdate(){ finish=chrono::system_clock::now(); } double TimeDist(){ return chrono::duration_cast<chrono::milliseconds>(finish-start).count(); } random_device rnd; mt19937 mt(rnd()); default_random_engine eng(rnd()); int NextInt(int minval,int maxval) { uniform_int_distribution<int> distr(minval,maxval); return distr(mt); } vector<vector<vector<ll>>> cross; const ll Mod=1e8; namespace Input{ int N; vector<vector<ll>> A; void Init(){ cin >> N; A.resize(N); rep(i,N){ rep(j,i+1){ ll a;cin >> a; A[i].push_back(a); } } cross.resize(N,vector<vector<ll>>(N,vector<ll>(N,0))); rep(i,N){ cross[i][N-1][i]=1; rrep(j,N){ rep(k,j+1){ cross[i][j][k]%=Mod; if(k<j) cross[i][j-1][k]+=cross[i][j][k]; if(k) cross[i][j-1][k-1]+=cross[i][j][k]; } } } } }; struct Pyramid{ int N; vector<vector<ll>> pyramid; vector<vector<ll>> dist; vector<vector<ll>> score; ll maxScore; P maxPos; void Init(){ N=Input::N; maxScore=0; pyramid.resize(N,vector<ll>(N,0)); dist.resize(N,vector<ll>(N,0)); score.resize(N,vector<ll>(N,0)); rep(i,N){ pyramid[N-1][i]=Input::A[N-1][i]; } for(int i=N-1;i>0;--i){ rep(j,i+1){ if(j<i) pyramid[i-1][j]+=pyramid[i][j]; if(j) pyramid[i-1][j-1]+=pyramid[i][j]; } } rep(i,N){ rep(j,i+1){ ScoreUpdate(i,j); if(chmax(maxScore,score[i][j])){ maxPos={i,j}; } } } } /// @brief 最下段(N-1,y)の数値をvalue分だけ変更する /// @param y 最下段の何個目か /// @param value 変化量 void Update(const int& y,const ll& value){ maxScore=0; rep(i,N){ rep(j,i+1){ ll add=value*cross[y][i][j]; add%=Mod; pyramid[i][j]+=add; if(cross[y][i][j]){ if(pyramid[i][j]<0){ pyramid[i][j]=Mod-abs(pyramid[i][j]%Mod); } pyramid[i][j]%=Mod; ScoreUpdate(i,j); } if(chmax(maxScore,score[i][j])){ maxPos={i,j}; } } } } // ll UpdateDown(const P& pos,const ll& val){ // if(val==0) return 0; // ll subValue=0; // if(x>N-1){ // if(pyramid[x+1][y]<=0 && pyramid[x+1][y+1]<=0){ // ll // } // } // auto [x,y]=pos; // pyramid[x][y]+=val; // if(pyramid[i][j]<0){ // pyramid[i][j]=Mod-abs(pyramid[i][j]%Mod); // } // pyramid[i][j]%=Mod; // ScoreUpdate(x,y); // return subValue; // } void ScoreUpdate(const int& x,const int& y){ score[x][y]=GetScore(x,y); } ll GetScore(const int& x,const int& y){ ll d=Input::A[x][y]-pyramid[x][y]; dist[x][y]=d; d=abs(d); return min(d,Mod-d); } }; struct Solver{ int N; Pyramid pyramid; ll bestScore; vector<ll> bestAns; void Init(){ N=Input::N; pyramid.Init(); bestScore=pyramid.maxScore; bestAns=pyramid.pyramid[N-1]; } void Solve(){ TimerStart(); while(TimeDist()<TimeLimit){ auto[x,y]=pyramid.maxPos; int l=pyramid.maxPos.second; int r=pyramid.maxPos.second+(N-pyramid.maxPos.first-1); int target=NextInt(l,r); ll targetDist=1250000*(2.0-TimeDist()/TimeLimit); ll targetValue=NextInt(max(0ll,Input::A[x][y]-targetDist),min(Mod-1ll,Input::A[x][y]+targetDist)); ll value=targetValue-pyramid.pyramid[x][y]; pyramid.Update(target,value); if(chmin(bestScore,pyramid.maxScore)){ bestAns=pyramid.pyramid[N-1]; } TimerUpdate(); } } void Output(){ rep(i,N){ if(i) cout << " "; cout << bestAns[i]; } cout << endl; } }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); Input::Init(); Solver solver; solver.Init(); solver.Solve(); solver.Output(); return 0; }