제출 #575247

#제출 시각아이디문제언어결과실행 시간메모리
575247BackNoobZoltan (COCI16_zoltan)C++14
112 / 140
106 ms7068 KiB
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define endl '\n'
#define MASK(i) (1LL << (i))
#define ull unsigned long long
#define ld long double
#define pb push_back
#define all(x) (x).begin() , (x).end()
#define BIT(x , i) ((x >> (i)) & 1)
#define TASK "task"
#define sz(s) (int) (s).size()
 
using namespace std;
const int mxN = 5e5 + 227;
const int inf = 1e9 + 277;
const int mod = 1e9 + 7;
const ll infll = 1e18 + 7;
const int base = 307;
const int LOG = 20;
 
template <typename T1, typename T2> bool minimize(T1 &a, T2 b) {
	if (a > b) {a = b; return true;} return false;
}
template <typename T1, typename T2> bool maximize(T1 &a, T2 b) {
	if (a < b) {a = b; return true;} return false;
}

void add(int &a, int b)
{
	a += b;
	if(a >= mod)
		a -= mod;
}
 
struct fenwick{
	int n;
	vector<int> bit, cnt;
	fenwick(){}
	fenwick(int _n) {
		n = _n;
		bit.resize(n + 7, -inf);
		cnt.resize(n + 7, 0);
	}

	void update(int pos, int val, int way)
	{
		for(; pos <= n; pos += pos & -pos) {
			if(maximize(bit[pos], val) == true) cnt[pos] = way;
			else {
				if(bit[pos] == val) add(cnt[pos], way);
			}
		}
	}

	pair<int, int> getans(int pos)
	{
		pair<int, int> res = {-1, 0};
		for(; pos > 0; pos -= pos & -pos) {
			if(maximize(res.fi, bit[pos]) == true) res.se = cnt[pos];
			else {
				if(res.fi == bit[pos]) add(res.se, cnt[pos]);
			}
		}
		return res;
	}
} ft;

int n;
int a[mxN];
pair<int, int> dp1[mxN];
pair<int, int> dp2[mxN];


void solve()
{
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];

	vector<int> val;
	for(int i = 1; i <= n; i++) val.pb(a[i]);
	sort(all(val));
	val.erase(unique(all(val)), val.end());
	for(int i = 1; i <= n; i++) 
		a[i] = lower_bound(all(val), a[i]) - val.begin() + 1;

	ft = fenwick(n);
	for(int i = n; i >= 1; i--) {
		maximize(dp1[a[i]], make_pair(1, 1));

		pair<int, int> tmp = ft.getans(a[i] - 1);
		// cout << dp1[a[i]].fi << endl;
		if(maximize(dp1[a[i]].fi, tmp.fi + 1) == true) {
			dp1[a[i]].se = tmp.se;
		}
		else {
			if(dp1[a[i]].fi == tmp.fi + 1)
				add(dp1[a[i]].se, tmp.se);
		}

		ft.update(a[i], dp1[a[i]].fi, dp1[a[i]].se);
	}

	ft = fenwick(n);

	for(int i = n; i >= 1; i--) {
		maximize(dp2[a[i]], make_pair(1, 1));
		pair<int, int> tmp = ft.getans(n - a[i] + 1 - 1);

		if(maximize(dp2[a[i]].fi, tmp.fi + 1) == true) {
			dp2[a[i]].se = tmp.se;
		}
		else {
			if(dp2[a[i]].fi == tmp.fi + 1)
				add(dp2[a[i]].se, tmp.se);
		}

		ft.update(n - a[i] + 1, dp2[a[i]].fi, dp2[a[i]].se);
	}


	pair<int, int> ans = {-1, 0};
	for(int i = n; i >= 1; i--) {
		if(maximize(ans.fi, dp1[a[i]].fi + dp2[a[i]].fi - 1) == true) {
			ans.se = 1LL * dp1[a[i]].se * dp2[a[i]].se % mod;
		}
		else {
			if(ans.fi == dp1[a[i]].fi + dp2[a[i]].fi - 1) {
				add(ans.se, 1LL * dp1[a[i]].se * dp2[a[i]].se);
			}
		}
	}

	// for(int i = 1; i <= n; i++) 
		// cout << dp1[a[i]].fi << ' ' << dp2[a[i]].fi << endl;

	// cout << ans.se << endl;
	for(int i = 1; i <= n - ans.fi; i++) ans.se = 1LL * ans.se * 2 % mod;
	cout << ans.fi << ' ' << ans.se << endl;
}
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen(TASK".in" , "r" , stdin);
    //freopen(TASK".out" , "w" , stdout);
 
    int tc = 1;
    // cin >> tc;
    while(tc--) {
    	solve();
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...