Submission #630874

# Submission time Handle Problem Language Result Execution time Memory
630874 2022-08-17T09:40:24 Z inksamurai Zoltan (COCI16_zoltan) C++17
140 / 140
327 ms 18392 KB
#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 time Memory 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 2 ms 340 KB Output is correct
11 Correct 181 ms 18068 KB Output is correct
12 Correct 145 ms 17764 KB Output is correct
13 Correct 164 ms 9552 KB Output is correct
14 Correct 196 ms 17820 KB Output is correct
15 Correct 265 ms 18084 KB Output is correct
16 Correct 327 ms 18376 KB Output is correct
17 Correct 243 ms 18392 KB Output is correct
18 Correct 227 ms 18304 KB Output is correct
19 Correct 245 ms 18392 KB Output is correct
20 Correct 233 ms 18308 KB Output is correct