Submission #1346879

#TimeUsernameProblemLanguageResultExecution timeMemory
1346879jahongirZoltan (COCI16_zoltan)C++20
140 / 140
171 ms10976 KiB
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;

const int mxn = 2e5, mod = 1e9+7;
int arr[mxn], pos[mxn];
int memo[mxn];

pii operator+(const pii &a, const pii &b){
	pii res = {max(a.first,b.first),0};
	if(res.first==a.first) res.second += a.second;
	if(res.first==b.first) res.second += b.second;
	if(res.second >= mod) res.second -= mod;
	return res;
}



struct SegTree{
	pii st[1<<19];

	SegTree(){
		fill(st,st+(1<<19),pii{-1,0});
	}

	void add(int i, int l, int r, int k, pii v){
		if(l==r){st[i] = st[i]+v; return;}
		int m = (l+r)>>1;
		if(k <= m) add(i<<1,l,m,k,v);
		else add(i<<1|1,m+1,r,k,v);
		st[i] = st[i<<1] + st[i<<1|1];
	}

	pii get(int i, int l, int r, int s, int e){
		if(r < s || l > e) return {-1,0};
		if(s <= l && r <= e) return st[i];
		int m = (l+r)>>1;
		return get(i<<1,l,m,s,e) + get(i<<1|1,m+1,r,s,e);
	}

};


signed main(){
	cin.tie(0)->sync_with_stdio(false);
	int n; cin >> n;
		
	for(int i = 0; i < n; i++){
		cin >> arr[i]; pos[i] = arr[i];
	}
	sort(pos,pos+n);
	int m = unique(pos,pos+n)-pos;
	for(int i = 0; i < n; i++)
		arr[i] = lower_bound(pos,pos+m,arr[i])-pos+1;

	m++;
	
	SegTree st,st2;
	st.add(1,0,m,m,{0,1});
	st2.add(1,0,m,0,{0,1});
	
	for(int i = n-1; i > 0; i--){
		auto v = st.get(1,0,m,arr[i]+1,m);
		v.first++;
		st.add(1,0,m,arr[i],v);
		v = st2.get(1,0,m,0,arr[i]-1);
		v.first++;
		st2.add(1,0,m,arr[i],v);
	}
	
	memo[0] = 1;
	for(int i = 1; i < n; i++){
		memo[i] = memo[i-1]<<1;
		if(memo[i] >= mod) memo[i] -= mod;
	}

	
	auto v1 = st.get(1,0,m,arr[0]+1,m);
	auto v2 = st2.get(1,0,m,0,arr[0]-1);
	
	pii ans = {v1.first+v2.first+1,0};
	ans.second = 1ll*v1.second*v2.second%mod*memo[n-ans.first]%mod;
	
	for(int i = 0; i < m; i++){
		v1 = st.get(1,0,m,i+1,m);
		v2 = st2.get(1,0,m,i,i);

		pii tmp = {v1.first+v2.first,0};
		tmp.second = 1ll*v1.second*v2.second%mod*memo[n-tmp.first-1]%mod;

		ans = ans + tmp;
	}
	
	cout << ans.first << ' ' << ans.second << '\n';
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...