Submission #630873

# Submission time Handle Problem Language Result Execution time Memory
630873 2022-08-17T09:38:21 Z inksamurai Zoltan (COCI16_zoltan) C++17
140 / 140
299 ms 18408 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){
	if(l.len!=r.len){
		return l.len>r.len?l:r;
	}
	l.wys+=r.wys;
	return l;
}
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 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 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 168 ms 17976 KB Output is correct
12 Correct 145 ms 17812 KB Output is correct
13 Correct 143 ms 9540 KB Output is correct
14 Correct 188 ms 17816 KB Output is correct
15 Correct 267 ms 17996 KB Output is correct
16 Correct 299 ms 18380 KB Output is correct
17 Correct 269 ms 18260 KB Output is correct
18 Correct 226 ms 18304 KB Output is correct
19 Correct 229 ms 18304 KB Output is correct
20 Correct 260 ms 18408 KB Output is correct