답안 #417761

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
417761 2021-06-04T08:50:56 Z MarcoMeijer Zoltan (COCI16_zoltan) C++14
140 / 140
437 ms 27212 KB
#include <bits/stdc++.h>
using namespace std;
 
// macros
typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> lll;
typedef tuple<int, int, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
typedef vector<lll> vlll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define FOR(a,b) for(auto& a : b)
#define all(a) a.begin(), a.end()
#define INF 1e18
#define EPS 1e-9
#define pb push_back
#define popb pop_back
#define fi first
#define se second
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
 
// input
template<class T> void IN(T& x) {cin >> x;}
template<class H, class... T> void IN(H& h, T&... t) {IN(h); IN(t...); }
 
// output
template<class T1, class T2> void OUT(const pair<T1,T2>& x);
template<class T> void OUT(const vector<T>& x);
template<class T> void OUT(const T& x) {cout << x;}
template<class H, class... T> void OUT(const H& h, const T&... t) {OUT(h); OUT(t...); }
template<class T1, class T2> void OUT(const pair<T1,T2>& x) {OUT(x.fi,' ',x.se);}
template<class T> void OUT(const vector<T>& x) {RE(i,x.size()) OUT(i==0?"":" ",x[i]);}
template<class... T> void OUTL(const T&... t) {OUT(t..., "\n"); }
template<class H> void OUTLS(const H& h) {OUTL(h); }
template<class H, class... T> void OUTLS(const H& h, const T&... t) {OUT(h,' '); OUTLS(t...); }
 
// dp
template<class T> bool ckmin(T&a, T&b) { bool bl = a > b; a = min(a,b); return bl;}
template<class T> bool ckmax(T&a, T&b) { bool bl = a < b; a = max(a,b); return bl;}
 
void program();
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    program();
}
 

// mod library
ll MOD=1e9+7;

inline ll mod(ll x_) {
    return (x_)%MOD;
}
ll modpow(ll x_, ll N_) {
    if(N_ == 0) return 1;
    ll a = modpow(x_,N_/2);
    a = (a*a)%MOD;
    if(N_%2) a = (a*x_)%MOD;
    return a;
}
ll inv(ll x_) {
    return modpow(x_, MOD-2);
}
class mi {
public:
    mi(ll v=0) {value = v;}
    mi  operator+ (ll rs) {return mod(value+rs);}
    mi  operator- (ll rs) {return mod(value-rs+MOD);}
    mi  operator* (ll rs) {return mod(value*rs);}
    mi  operator/ (ll rs) {return mod(value*inv(rs));}
    mi& operator+=(ll rs) {*this = (*this)+rs; return *this;}
    mi& operator-=(ll rs) {*this = (*this)-rs; return *this;}
    mi& operator*=(ll rs) {*this = (*this)*rs; return *this;}
    mi& operator/=(ll rs) {*this = (*this)/rs; return *this;}
    operator ll&() {return value;}

    ll value;
};
typedef vector<mi> vmi;

//===================//
//   begin program   //
//===================//
 
const int MX = 5e5;
const int N = (1<<20);

int n, a[MX];
int m, b[MX];
int lis[MX];

// fenwick tree
int FT[MX];
void addFT(int i, int value) {
    for(i++; i<=n; i+=i&-i) FT[i] = max(FT[i],value);
}
int getFT(int i) {
    int ans = 0;
    for(i++; i; i-=i&-i) ans = max(ans,FT[i]);
    return ans;
}
void addSM(int i, mi value) {
    for(i++; i<MX; i+=i&-i) FT[i] = (mi)FT[i] + value;
}
mi getSM(int i) {
    mi ans = 0;
    for(i++; i; i-=i&-i) ans += (mi)FT[i];
    return ans;
}

vi layer[MX];
int c[MX], dpi[MX], dpe[MX];

void program() {
    IN(n);
    RE(i,n) IN(a[i]);
    REV(i,1,n) b[m++] = a[i];
    RE(i,n) b[m++] = a[i];

    // fill c
    RE(i,m) c[i] = 1;
    c[m/2] = mi(1)/mi(2);

    // coördinate compression
    vi difa;
    RE(i,n) difa.pb(a[i]);
    sort(all(difa));
    RE(i,n) a[i] = lower_bound(all(difa),a[i]) - difa.begin();
    RE(i,m) b[i] = lower_bound(all(difa),b[i]) - difa.begin();

    // finding lis
    RE(i,m) {
        lis[i] = getFT(b[i]-1)+1;
        addFT(b[i],lis[i]);
    }
    RE(i,m) layer[lis[i]].pb(i);

    RE(i,MX) FT[i] = 0;

    RE1(i,n) {
        vi pq;
        FOR(j,layer[i-1])
            pq.pb(j);
        FOR(j,layer[i])
            pq.pb(j);
        sort(all(pq));
        FOR(j,pq) {
            if(lis[j] == i) {
                dpe[j] = (mi)c[j]*getSM(b[j]-1);
                if(i == 1) dpe[j] = c[j];
                if(j == m/2) {
                    dpi[j] = dpe[j];
                    dpe[j] = 0;
                }
            } else {
                addSM(b[j],dpe[j]);
            }
        }
        FOR(j,layer[i-1]) addSM(b[j],-dpe[j]);
    }

    RE1(i,n) {
        vi pq;
        FOR(j,layer[i-1])
            pq.pb(j);
        FOR(j,layer[i])
            pq.pb(j);
        sort(all(pq));
        FOR(j,pq) {
            if(lis[j] == i) {
                if(j == m/2) continue;
                dpi[j] = (mi)c[j]*getSM(b[j]-1);
            } else {
                addSM(b[j],dpi[j]);
            }
        }
        FOR(j,layer[i-1]) addSM(b[j],-dpi[j]);
    }

    int ans=0;
    RE(i,m) ans = max(ans,lis[i]);

    mi res1=0;
    RE(i,m) if(lis[i] == ans) res1 += (mi)dpi[i];
    res1 *= modpow(2,n-ans+1);
    mi res2=0;
    RE(i,m) if(lis[i] == ans) res2 += (mi)dpe[i];
    res2 *= modpow(2,n-ans-1);
    res1 += res2;

    OUTLS(ans,(ll)res1);
}
# 결과 실행 시간 메모리 Grader output
1 Correct 11 ms 14028 KB Output is correct
2 Correct 11 ms 14052 KB Output is correct
3 Correct 11 ms 14028 KB Output is correct
4 Correct 11 ms 14028 KB Output is correct
5 Correct 11 ms 14056 KB Output is correct
6 Correct 11 ms 13944 KB Output is correct
7 Correct 12 ms 14076 KB Output is correct
8 Correct 12 ms 14028 KB Output is correct
9 Correct 12 ms 14028 KB Output is correct
10 Correct 12 ms 14028 KB Output is correct
11 Correct 283 ms 25292 KB Output is correct
12 Correct 239 ms 23736 KB Output is correct
13 Correct 212 ms 23292 KB Output is correct
14 Correct 294 ms 22152 KB Output is correct
15 Correct 381 ms 23940 KB Output is correct
16 Correct 437 ms 25480 KB Output is correct
17 Correct 349 ms 27160 KB Output is correct
18 Correct 347 ms 27180 KB Output is correct
19 Correct 375 ms 27072 KB Output is correct
20 Correct 365 ms 27212 KB Output is correct