제출 #488631

#제출 시각아이디문제언어결과실행 시간메모리
488631VictorZoltan (COCI16_zoltan)C++17
21 / 140
526 ms58496 KiB
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = (a); i < (b); ++i) #define per(i, a, b) for (int i = (b - 1); i >= (a); --i) #define trav(a, x) for (auto &a : x) #define all(x) x.begin(), x.end() #define sz(x) x.size() #define pb push_back #define debug(x) cout << #x << " = " << x << endl #define umap unordered_map #define uset unordered_set typedef pair<int, int> ii; typedef pair<int, ii> iii; typedef vector<int> vi; typedef vector<ii> vii; typedef vector<vi> vvi; typedef long long ll; typedef pair<ll, ll> pll; typedef vector<ll> vll; typedef vector<pll> vpll; const int INF = 1'000'000'007; struct Node { Node *l, *r; int len = 0, lo, hi; ll cnt = 1; Node(int L, int R) : lo(L), hi(R) { if (hi - lo != 1) { int mid = (lo + hi) >> 1; l = new Node(lo, mid); r = new Node(mid, hi); } } pair<int, ll> query(int L, int R) { if (hi <= L || R <= lo) return {0, 1}; if (L <= lo && hi <= R) return {len, cnt}; return combine(l->query(L, R), r->query(L, R)); } void update(int pos, int nlen, ll ncnt) { if (pos < lo || hi <= pos) return; if (hi - lo == 1) { tie(len, cnt) = combine({len, cnt}, {nlen, ncnt}); return; } l->update(pos,nlen,cnt); r->update(pos,nlen,ncnt); tie(len,cnt)=combine({l->len,l->cnt},{r->len,r->cnt}); } pair<int, ll> combine(pair<int, ll> v1, pair<int, ll> v2) { int l1, l2; ll cnt1, cnt2; tie(l1, cnt1) = v1; tie(l2, cnt2) = v2; if (l2 < l1) return {l1, cnt1}; if (l1 < l2) return {l2, cnt2}; return {l1, (cnt1 + cnt2) % INF}; } }; int main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); int ans = 0, arr[200001], n; ll cnt = 0; set<int> nums; umap<int, int> compress; cin >> n; rep(i, 0, n) cin >> arr[i], nums.insert(arr[i]); int pos = 0; trav(num, nums) compress[num] = pos++; rep(i, 0, n) arr[i] = compress[arr[i]]; Node lis(0,pos); Node lds(0,pos); per(i,0,n){ int num=arr[i]; int len_lis,len_lds; ll cnt_lis,cnt_lds; tie(len_lis,cnt_lis)=lis.query(0,num); tie(len_lds,cnt_lds)=lds.query(num+1,pos); ++len_lis; ++len_lds; lis.update(num,len_lis,cnt_lis); lds.update(num,len_lds,cnt_lds); int cur_len=len_lis+len_lds-1; ll cur_cnt=cnt_lis*cnt_lds; if(cur_len>ans){ ans=cur_len; cnt=0; } if(cur_len>=ans)cnt=(cnt+cur_cnt)%INF; } rep(i,0,n-ans)cnt=(cnt<<1)%INF; cout<<ans<<' '<<cnt<<endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...