比赛 2022级DP专题练习赛7 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 数列 最终得分 100
用户昵称 op_组撒头屯 运行时间 1.612 s
代码语言 C++ 内存使用 9.35 MiB
提交时间 2023-02-27 21:38:00
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define vi vector<int>
#define si set<int>
#define unsi unordered_set<int>
#define qi queue<int>
#define sti stack<int>
#define pqi priority_queue<int>
#define mii map<int,int>
#define unmii unordered_map<int,int>
#define fi first
#define se second
#define pb push_back
#define clr(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
const int N=200000+5;
const ll mod=1000000007;
int n;
int a[2*N],b[2*N],cnt=0,len[N];
pii f[2*N],tr[4*N];
void pushup(int pt){
    if (tr[pt*2].fi==tr[pt*2+1].fi)tr[pt].se=(tr[pt*2].se+tr[pt*2+1].se)%mod;
    else tr[pt].se=(tr[pt*2].fi>tr[pt*2+1].fi)?tr[pt*2].se:tr[pt*2+1].se;
    tr[pt].fi=max(tr[pt*2].fi,tr[pt*2+1].fi);
}
void calc(pii &now,pii x){
    if (x.fi==now.fi)(now.se+=x.se)%=mod;
    else if (x.fi>now.fi)now=x;
}
void build(int pt,int l,int r){
    tr[pt]={0,0};
    if (l==r)return ;
    int mid=(l+r)/2;
    build(pt*2,l,mid);build(pt*2+1,mid+1,r);
}
void add(int pt,int l,int r,int pos,pii w){
    if (l==r){
        calc(tr[pt],w);return ;
    }
    int mid=(l+r)/2;
    if (pos<=mid)add(pt*2,l,mid,pos,w);
    else add(pt*2+1,mid+1,r,pos,w);
    pushup(pt);return ;
}
pii query(int pt,int l,int r,int ql,int qr){
    if (ql<=l&&r<=qr)return tr[pt];
    int mid=(l+r)/2;pii ans={0,0};
    if (ql<=mid)calc(ans,query(pt*2,l,mid,ql,qr));
    if (mid+1<=qr) calc(ans,query(pt*2+1,mid+1,r,ql,qr));
    return ans;
}
ll fst(ll x,ll y){
    if (y==-1)return (mod+1)/2;
    ll ans=1;
    while(y){
        if (y&1)ans=ans*x%mod;
        x=x*x%mod;y>>=1;
    }return ans;
}
int main(){
	freopen ("lisshulie.in","r",stdin);
	freopen ("lisshulie.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)scanf("%d",&a[i]),b[++cnt]=a[i];
	sort(b+1,b+cnt+1);
	cnt=unique(b+1,b+cnt+1)-b-1;
	for (int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
	reverse(a+1,a+n+1);
	for (int i=1;i<=n;i++)a[i+n]=a[n-i+1];
	int ans=0;ll tot=0;
	build(1,0,cnt);
	for (int i=1;i<=2*n;i++){
	    //cout<<a[i]<<" ";
	    f[i]=query(1,0,cnt,0,a[i]-1);f[i].fi++;
	    if (f[i].fi==1)f[i].se++;
	    //cout<<f[i].fi<<" ";
        ans=max(ans,f[i].fi);add(1,0,cnt,a[i],f[i]);
    }
    for (int i=1;i<=2*n;i++){
        if (f[i].fi==ans)(tot+=f[i].se)%=mod;
    }
    printf("%d %lld\n",ans,tot*fst(2,n-ans-1)%mod);
}