結果
問題 | No.335 門松宝くじ |
ユーザー | koyumeishi |
提出日時 | 2016-01-15 23:35:38 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 387 ms / 2,000 ms |
コード長 | 4,225 bytes |
コンパイル時間 | 1,219 ms |
コンパイル使用メモリ | 108,200 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-09-19 19:33:09 |
合計ジャッジ時間 | 4,266 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 10 |
ソースコード
#include <iostream> #include <vector> #include <cstdio> #include <sstream> #include <map> #include <string> #include <algorithm> #include <queue> #include <cmath> #include <functional> #include <set> #include <ctime> #include <random> using namespace std; template<class T> istream& operator >> (istream& is, vector<T>& vec){for(T& val: vec) is >> val; return is;} template<class T> istream& operator , (istream& is, T& val){ return is >> val;} template<class T> ostream& operator << (ostream& os, vector<T>& vec){for(int i=0; i<vec.size(); i++) os << vec[i] << (i==vec.size()-1?"\n":" ");return os;} template<class T> ostream& operator , (ostream& os, T& val){ return os << " " << val;} template<class T> ostream& operator >> (ostream& os, T& val){ return os << " " << val;} bool is_kadomatsu_sequence(vector<int> x){ if(x.size() != 3) return false; if(x[0] < x[1] && x[1] > x[2] && x[2] != x[0]) return true; if(x[0] > x[1] && x[1] < x[2] && x[2] != x[0]) return true; return false; } //segment tree //using std::function as comparing function template<class Value = int> class SegmentTree{ int n; vector<Value> V; Value DEFAULT_VALUE; //evaluation function static Value default_evaluate(Value a, Value b){ return max(a,b); } function< Value(Value, Value) > evaluate; //return evaluated value in [a,b) //T[at] covers [l,r) Value RangeEvaluation(int a, int b, int at, int l, int r){ //out of range if(r <= a || b <= l) return DEFAULT_VALUE; //covered if(a <= l && r <= b) return V[at]; //partially covered else{ Value val_left = RangeEvaluation(a,b, at*2+1, l, (l+r)/2); Value val_right = RangeEvaluation(a,b, at*2+2, (l+r)/2, r); return evaluate(val_left, val_right); } } public: SegmentTree(int size, Value DEFAULT , function< Value(Value, Value) > eval /*= default_evaluate*/){ DEFAULT_VALUE = DEFAULT; evaluate = eval; n=1; while(n<size) n <<= 1; V = vector<Value>(2*n - 1, DEFAULT_VALUE); } void update(int at, Value new_val){ at += n-1; V[at] = new_val; while(at>0){ at = (at-1)/2; V[at] = evaluate(V[at*2 + 1], V[at*2 + 2]); } } //return evaluated value in [l,r) Value RangeEvaluation(int l, int r){ if(l>=r) return DEFAULT_VALUE; if(l>=n) return DEFAULT_VALUE; return RangeEvaluation(l,r, 0, 0, n); } }; int main(){ int n,m; cin >> n,m; vector<vector<int>> a(m, vector<int>(n)); cin >> a; function<int(int,int)> my_min = [&](int l, int r){return min(l,r);}; function<int(int,int)> my_max = [&](int l, int r){return max(l,r);}; long long max_ = 0; double p = 1.0 / (n * (n-1) * 0.5); int val = 0; for(int i=0; i<m; i++){ SegmentTree<int> seg_min(n, 2000, my_min); SegmentTree<int> seg_max(n, -1, my_max); for(int j=0; j<n; j++){ seg_min.update(j, a[i][j]); seg_max.update(j, a[i][j]); } long long sum = 0; for(int x=0; x<n; x++){ for(int y=x+1; y<n; y++){ int ans = 0; int l = a[i][x]; int r = a[i][y]; if(l<r){ // z > l < r if(x>0){ int z = seg_max.RangeEvaluation(0,x); if(z > l){ int hoge = max(z, r); if(ans<hoge){ ans = hoge; } } } }else{ // z < l > r if(x>0){ int z = seg_min.RangeEvaluation(0,x); if(z < l){ int hoge = l; if(ans<hoge){ ans = hoge; } } } } if(r-l > 1){ // l < z > r int z = seg_max.RangeEvaluation(l+1, r); if(z > max(l,r)){ int hoge = z; if(ans<hoge){ ans = hoge; } } // l > z < r z = seg_min.RangeEvaluation(l+1, r); if(z < min(l,r)){ int hoge = max(l,r); if(ans<hoge){ ans = hoge; } } } if(l<r){ // l < r > z if(n-r > 1){ int z = seg_min.RangeEvaluation(r+1, n); if(z < r){ int hoge = r; if(ans<hoge){ ans = hoge; } } } }else{ // l > r < z if(n-r > 1){ int z = seg_max.RangeEvaluation(r+1, n); if(z > r){ int hoge = max(l,z); if(ans<hoge){ ans = hoge; } } } } sum += ans; } } if(max_ < sum){ max_ = sum; val = i; } } cout << val << endl; return 0; }