#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <map>
#include <set>
#include <iomanip>
#include <queue>
#include <stack>
using namespace std;
#define vt vector
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define FORR1(x) for(int i = 0; i < (x); i++)
#define FORR2(i,x) for (int (i) = 0; (i) < (x); (i)++)
#define MOD 1000000007
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef long double ld;
typedef vt<int> vi;
typedef pair<int,pair<int,int>> piii;
struct fwtree{
vi arr;
int sz;
void init(int n){
arr.resize(n+1);
sz = n;
FORR1(n+1)arr[i] = 0;
}
//remember difference between 0- and 1- indexing
void add(int index, int val){
while(index <= sz){
arr[index]+=val;
index+=index&-index;
}
}
ll get(int index){
ll val = 0;
while(index!=0){
val+=arr[index];
index-=index&-index;
}
return val;
}
ll get(int l, int r){
return get(r)-get(l-1);
}
};
int N, O, M;
vi ceo;
ll fastexp(ll n, int m){
if(m==0)return 1;
ll cur = fastexp(n,m/2);
cur = cur*cur;
cur%=MOD;
if(m&1){
cur*=n;
cur%=MOD;
}
return cur;
}
ll inv(ll x){
return fastexp(x,MOD-2);
}
vt<vi> adjlist;
int degree[200005];
int dp[200005];
int ans = 0;
void dfs_dp(int node, int par){
int cur = 0;
for(auto& e: adjlist[node]){
if(e!=par){
dfs_dp(e,node);
cur = max(cur,dp[e]);
}
}
dp[node] = max(cur,degree[node]);
}
void dfs_ans(int node, int par){
int k = 0;
for(auto& e: adjlist[node]){
if(e!=par){
dfs_ans(e,node);
if(dp[e]<=2)k++;
}
}
if(k>1)ans+=k-1;
}
ll fac[500005];
ll invfac[500005];
bool arr[102][102][102];
vt<vi> adj;
int clr[102];
bool visited[102];
bool chk = true;
void dfs(int node){
visited[node] = true;
for(auto& e: adj[node]){
if(visited[e]){
if((clr[e]^1)!=clr[node]){
chk = false;
}else{
clr[e] = clr[node]^1;
dfs(e);
}
}
}
}
vt<vi> tr;
void solve(){
int n;
cin>>n;
vi arr(n);
FORR1(n)cin>>arr[i];
vi up(n);
vi dn(n);
vi upct(n);
vi dnct(n);
vi curup(n+1);
vi curdn(n+1);
vi indup(n+1);
vi inddn(n+1);
int at1 = 1;
int at2 = 1;
FORR1(n+1){
curup[i] = -1;
curdn[i] = -1;
indup[i] = -1;
inddn[i] = -1;
}
vt<vt<pii>> adjup(n+1);
vt<vt<pii>> adjdn(n+1);
vi relup(n+1);
vi reldn(n+1);
vi sumup(n+1);
vi sumdn(n+1);
FORR1(n+1){
sumup[i] = sumdn[i] = relup[i] = reldn[i] = 0;
}
for(int i = n-1; i >=0; i--){
if(i==n-1){
curdn[1] = arr[i];
inddn[1] = i;
dn[i] = 1;
dnct[i] = 1;
sumdn[1] = 1;
adjdn[1].pb({arr[i],1});
}else{
if(arr[i]>curdn[at1]){
at1++;
curdn[at1] = arr[i];
inddn[at1] = i;
while(arr[i]<=adjdn[at1-1][reldn[at1-1]].first){
sumdn[at1-1]-=adjdn[at1-1][reldn[at1-1]].second;
if(sumdn[at1-1]<0)sumdn[at1-1]+=MOD;
reldn[at1-1]++;
}
dn[i] = at1;
dnct[i] = sumdn[at1-1];
adjdn[at1].pb({arr[i],dnct[i]});
sumdn[at1]+=dnct[i];
}else{
int l = 1;
int r = at1;
while(l!=r){
int mid = (l+r)>>1;
if(curdn[mid]<arr[i]){
l = mid+1;
}else{
r = mid;
}
}
curdn[l] = arr[i];
inddn[l] = i;
dn[i] = l;
if(l==1){
dnct[i] = 1;
}else{
while(arr[i]<=adjdn[l-1][reldn[l-1]].first){
sumdn[l-1]-=adjdn[l-1][reldn[l-1]].second;
if(sumdn[l-1]<0)sumdn[l-1]+=MOD;
reldn[l-1]++;
}
dnct[i] = sumdn[l-1];
}
adjdn[l].pb({arr[i],dnct[i]});
sumdn[l]+=dnct[i];
if(sumdn[l]>=MOD)sumdn[l]-=MOD;
}
}
}
for(int i = n-1; i >=0; i--){
if(i==n-1){
curup[1] = arr[i];
indup[1] = i;
up[i] = 1;
upct[i] = 1;
sumup[1] = 1;
adjup[1].pb({arr[i],1});
}else{
if(arr[i]<curup[at2]){
at2++;
curup[at2] = arr[i];
indup[at2] = i;
while(arr[i]>=adjup[at2-1][relup[at2-1]].first){
sumup[at2-1]-=adjup[at2-1][relup[at2-1]].second;
if(sumup[at2-1]<0)sumup[at2-1]+=MOD;
relup[at2-1]++;
}
up[i] = at2;
upct[i] = sumup[at2-1];
adjup[at2].pb({arr[i],upct[i]});
sumup[at2]+=upct[i];
}else{
int l = 1;
int r = at2;
while(l!=r){
int mid = (l+r)>>1;
if(curup[mid]>arr[i]){
l = mid+1;
}else{
r = mid;
}
}
curup[l] = arr[i];
indup[l] = i;
up[i] = l;
if(l==1){
upct[i] = 1;
}else{
while(arr[i]>=adjup[l-1][relup[l-1]].first){
sumup[l-1]-=adjup[l-1][relup[l-1]].second;
if(sumup[l-1]<0)sumup[l-1]+=MOD;
relup[l-1]++;
}
upct[i] = sumup[l-1];
}
adjup[l].pb({arr[i],upct[i]});
sumup[l]+=upct[i];
if(sumup[l]>=MOD)sumup[l]-=MOD;
}
}
}
/*FORR1(n){
cout<<dn[i]<<" "<<dnct[i]<<'\n';
}
cout<<"----\n";
FORR1(n){
cout<<up[i]<<" "<<upct[i]<<'\n';
}*/
int Max = 0;
FORR1(n){
Max = max(Max, up[i]+dn[i]-1);
}
int val = 1;
for(int i = 0; i < n-Max; i++){
val*=2;
val%=MOD;
}
ll ans = 0;
FORR1(n){
if(up[i]+dn[i]-1==Max){
ans+=(ll)upct[i]*dnct[i];
ans%=MOD;
}
}
cout<<Max<<" "<<ans*val%MOD<<'\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t = 1;
//cin>>t;
while(t--) {
solve();
}
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
2 |
Correct |
0 ms |
212 KB |
Output is correct |
3 |
Correct |
0 ms |
212 KB |
Output is correct |
4 |
Correct |
0 ms |
212 KB |
Output is correct |
5 |
Correct |
0 ms |
212 KB |
Output is correct |
6 |
Correct |
0 ms |
212 KB |
Output is correct |
7 |
Correct |
1 ms |
340 KB |
Output is correct |
8 |
Correct |
1 ms |
340 KB |
Output is correct |
9 |
Correct |
1 ms |
340 KB |
Output is correct |
10 |
Correct |
1 ms |
340 KB |
Output is correct |
11 |
Correct |
42 ms |
20620 KB |
Output is correct |
12 |
Correct |
35 ms |
17984 KB |
Output is correct |
13 |
Correct |
31 ms |
16960 KB |
Output is correct |
14 |
Correct |
43 ms |
17096 KB |
Output is correct |
15 |
Correct |
54 ms |
21428 KB |
Output is correct |
16 |
Correct |
64 ms |
24636 KB |
Output is correct |
17 |
Correct |
63 ms |
26796 KB |
Output is correct |
18 |
Correct |
74 ms |
27084 KB |
Output is correct |
19 |
Correct |
62 ms |
26900 KB |
Output is correct |
20 |
Correct |
65 ms |
26912 KB |
Output is correct |