Submission #630874

#TimeUsernameProblemLanguageResultExecution timeMemory
630874inksamuraiZoltan (COCI16_zoltan)C++17
140 / 140
327 ms18392 KiB
#include <bits/stdc++.h> using namespace std; #define rep(i,n) for(int i=0;i<n;i++) #define rng(i,c,n) for(int i=c;i<n;i++) #define per(i,n) for(int i=n-1;i>=0;i--) #define fi first #define se second #define pb push_back #define sz(a) (int)a.size() #define vec(...) vector<__VA_ARGS__> #define _3phCa4T ios::sync_with_stdio(0),cin.tie(0) typedef long long ll; using pii=pair<int,int>; using vi=vector<int>; void print(){cout<<'\n';} template<class h,class...t> void print(const h&v,const t&...u){cout<<v<<' ',print(u...);} // e // snuke's mod int template<ll mod> struct modint{ ll x; modint(ll x=0):x((x%mod+mod)%mod){} modint& operator+=(const modint a){if((x+=a.x)>=mod)x-=mod; return *this;} modint& operator-=(const modint a){if((x+=mod-a.x)>=mod)x-=mod; return *this;} modint& operator*=(const modint a){(x*=a.x)%=mod; return *this;} modint operator+(const modint a)const{modint res(*this); return res+=a;} modint operator-(const modint a)const{modint res(*this); return res-=a;} modint operator*(const modint a)const{modint res(*this); return res*=a;} modint pow(ll n)const{ modint res=1,x(*this); while(n){ if(n&1)res*=x; x*=x; n/=2; } return res; } }; using mint=modint<1000000007>; struct N{ int len; mint wys; N(int _len=0,mint _wys=0): len(_len),wys(_wys){} }; N op(N l,N r){return r.len!=l.len?(l.len>r.len?l:r):N(l.len,l.wys+r.wys);} N e(){return {0,0};} template<class S,S (*op)(S,S),S (*e)()> struct segtree{ int n; vec(S) seg; segtree(int _n){ init(_n); } void init(int _n){ n=1; while(n<=_n){ n*=2; } seg=vec(S)(2*n); n=_n; } S prod(int node,int l,int r,int _l,int _r){ if(l>=_r or r<=_l){ return e(); } if(_l<=l and r<=_r){ return seg[node]; } int m=(l+r)>>1; return op(prod(node*2,l,m,_l,_r),prod(node*2+1,m,r,_l,_r)); } S prod(int l,int r){ return prod(1,0,n,l,r); } void set(int node,int l,int r,int pos,const S&x){ if(l==r-1){ seg[node]=x; return; } int m=(l+r)/2; if(pos<m){ set(node*2,l,m,pos,x); }else{ set(node*2+1,m,r,pos,x); } seg[node]=op(seg[node*2],seg[node*2+1]); } void set(int pos,const S&x){ set(1,0,n,pos,x); } S get(int pos){ return prod(1,0,n,pos,pos+1); } }; signed main(){ _3phCa4T; int n; cin>>n; vi a(n); rep(i,n){ cin>>a[i]; } vi tmp=a; sort(tmp.begin(), tmp.end()); tmp.erase(unique(tmp.begin(), tmp.end()),tmp.end()); const int m=sz(tmp); rep(i,n){ a[i]=lower_bound(tmp.begin(), tmp.end(),a[i])-tmp.begin(); } int len=0; mint wys=0; segtree<N,op,e> fseg(m),gseg(m); per(i,n){ int v=a[i]; N fres=fseg.prod(v+1,m); N gres=gseg.prod(0,v); if(!fres.len) fres.wys=1; if(!gres.len) gres.wys=1; int now=fres.len+gres.len+1; if(now>len){ len=now; wys=fres.wys*gres.wys*mint(2).pow(n-now); }else if(now==len){ wys+=fres.wys*gres.wys*mint(2).pow(n-now); } fres.len+=1; gres.len+=1; fseg.set(v,op(fseg.get(v),fres)); gseg.set(v,op(gseg.get(v),gres)); } print(len,wys.x); }
#Verdict Execution timeMemoryGrader output
Fetching results...