思路就是对于每个点都找出来以它为起点的最大上升序列和最大下降序列,然后计算方案数。
怀疑是某个地方没有取模(也许?),但是找不出来。
与题解做法稍有区别,因为我统计序列长度的时候没有把当前点统计进去,不知道会不会有影响
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+10 , mod = 1e9+7;
int n;
int a[N] , b[N];
struct node
{
int l , r;
int cnt , len;//cnt是方案数,len是序列长度
}tr[N<<2];
int f[N] , cntf[N] , g[N] , cntg[N];
inline void pushup (node &rt , node l , node r)
{
rt.l = l.l , rt.r = r.r , rt.cnt = 0;
rt.len = max(l.len , r.len);
if (rt.len==l.len) rt.cnt += l.cnt , rt.cnt%=mod;
if (rt.len==r.len) rt.cnt += r.cnt , rt.cnt%=mod;
}
inline void pushup (int u)
{
pushup(tr[u] , tr[u<<1] , tr[u<<1|1]);
}
void build (int u , int l , int r)
{
tr[u] = {l , r , 0 , 0};
if (l==r)
{
return;
}
int mid = (l+r)>>1;
build(u<<1 , l , mid) , build(u<<1|1 , mid+1 , r);
}
void modify (int u , int id , int len , int x)
{
if (tr[u].l==id && tr[u].r==id)
{
if (tr[u].len==len) tr[u].cnt += x , tr[u].cnt%=mod;
else tr[u].len = len , tr[u].cnt = x;
}
else
{
int mid = (tr[u].l+tr[u].r)>>1;
if (id<=mid) modify(u<<1 , id , len , x);
else modify(u<<1|1 , id , len , x);
pushup(u);
}
}
node query (int u , int l , int r)
{
if (l<=tr[u].l && tr[u].r<=r)
{
return tr[u];
}
else
{
int mid = (tr[u].l+tr[u].r)>>1;
if (l<=mid)
{
if (r>mid)
{
node res;
pushup(res , query(u<<1 , l , r) , query(u<<1|1 , l , r));
return res;
}
return query(u<<1 , l , r);
}
else return query(u<<1|1 , l , r);
}
}
inline int qmi (int a , int b)
{
int res = 1;
while (b)
{
if (b&1) res = res*a%mod;
a = a*a%mod;
b>>=1;
}
return res;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n;
for (int i=1 ; i<=n ; i++)
{
cin >> a[i];
b[i] = a[i];
}
sort(b+1 , b+1+n);
int len_b = unique(b+1 , b+1+n)-b-1;
for (int i=1 ; i<=n ; i++)
{
a[i] = lower_bound(b+1 , b+1+len_b , a[i])-b;
}//离散化
build(1 , 1 , n);
for (int i=n ; i>=1 ; i--)
{
node t;
if (a[i]+1<=n) t = query(1 , a[i]+1 , n);
else t = {1 , n , 0 , 0};
modify(1 , a[i] , t.len+1 , max(t.cnt , 1ll));
f[i] = t.len , cntf[i] = max(t.cnt , 1ll);
}
build(1 , 1 , n);//初始化,求最大下降序列
for (int i=n ; i>=1 ; i--)
{
node t;
if (a[i]-1>=1) t = query(1 , 1 , a[i]-1);
else t = {1 , n , 0 , 0};
modify(1 , a[i] , t.len+1 , max(t.cnt , 1ll));
g[i] = t.len , cntg[i] = max(t.cnt , 1ll);
}
int mx = -1e9 , sum = 0;
for (int i=1 ; i<=n ; i++)
{
int len = f[i]+g[i]+1;
if (mx<len)
{
mx = len;
sum = (qmi(2 , n-f[i]-g[i]-1)*(cntf[i]%mod)*(cntg[i]%mod))%mod;
}
else if (mx==len)
{
sum = (sum+(qmi(2 , n-f[i]-g[i]-1)*(cntf[i]%mod)*(cntg[i]%mod))%mod)%mod;
}
}
cout << mx << ' ' << sum%mod << '\n';
return 0;
}