Submission #593020

# Submission time Handle Problem Language Result Execution time Memory
593020 2022-07-10T08:02:58 Z Andyvanh1 Zoltan (COCI16_zoltan) C++14
140 / 140
74 ms 27084 KB
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <map>
#include <set>
#include <iomanip>
#include <queue>
#include <stack>



using namespace std;

#define vt vector
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define FORR1(x) for(int i = 0; i < (x); i++)
#define FORR2(i,x) for (int (i) = 0; (i) < (x); (i)++)
#define MOD 1000000007

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef long double ld;
typedef vt<int> vi;
typedef pair<int,pair<int,int>> piii;

struct fwtree{
    vi arr;
    int sz;

    void init(int n){
        arr.resize(n+1);
        sz = n;
        FORR1(n+1)arr[i] = 0;
    }

    //remember difference between 0- and 1- indexing
    void add(int index, int val){
        while(index <= sz){
            arr[index]+=val;
            index+=index&-index;
        }
    }

    ll get(int index){
        ll val = 0;
        while(index!=0){
            val+=arr[index];
            index-=index&-index;
        }
        return val;
    }

    ll get(int l, int r){
        return get(r)-get(l-1);
    }

};

int N, O, M;
vi ceo;
ll fastexp(ll n, int m){
    if(m==0)return 1;
    ll cur = fastexp(n,m/2);
    cur = cur*cur;
    cur%=MOD;
    if(m&1){
        cur*=n;
        cur%=MOD;
    }
    return cur;
}

ll inv(ll x){
    return fastexp(x,MOD-2);
}



vt<vi> adjlist;
int degree[200005];
int dp[200005];
int ans = 0;

void dfs_dp(int node, int par){
    int cur = 0;
    for(auto& e: adjlist[node]){
        if(e!=par){
            dfs_dp(e,node);
            cur = max(cur,dp[e]);
        }
    }
    dp[node] = max(cur,degree[node]);
}

void dfs_ans(int node, int par){
    int k = 0;
    for(auto& e: adjlist[node]){
        if(e!=par){
            dfs_ans(e,node);
            if(dp[e]<=2)k++;
        }
    }
    if(k>1)ans+=k-1;
}

ll fac[500005];
ll invfac[500005];
bool arr[102][102][102];
vt<vi> adj;
int clr[102];

bool visited[102];
bool chk = true;
void dfs(int node){
    visited[node] = true;
    for(auto& e: adj[node]){
        if(visited[e]){
            if((clr[e]^1)!=clr[node]){
                chk = false;
            }else{
                clr[e] = clr[node]^1;
                dfs(e);
            }
        }
    }
}
vt<vi> tr;

void solve(){
    int n;
    cin>>n;
    vi arr(n);
    FORR1(n)cin>>arr[i];
    vi up(n);
    vi dn(n);
    vi upct(n);
    vi dnct(n);
    vi curup(n+1);
    vi curdn(n+1);
    vi indup(n+1);
    vi inddn(n+1);
    int at1 = 1;
    int at2 = 1;
    FORR1(n+1){
        curup[i] = -1;
        curdn[i] = -1;
        indup[i] = -1;
        inddn[i] = -1;
    }
    vt<vt<pii>> adjup(n+1);
    vt<vt<pii>> adjdn(n+1);
    vi relup(n+1);
    vi reldn(n+1);
    vi sumup(n+1);
    vi sumdn(n+1);
    FORR1(n+1){
        sumup[i] = sumdn[i] = relup[i] = reldn[i] = 0;
    }

    for(int i = n-1; i >=0; i--){
        if(i==n-1){
            curdn[1] = arr[i];
            inddn[1] = i;
            dn[i] = 1;
            dnct[i] = 1;
            sumdn[1] = 1;
            adjdn[1].pb({arr[i],1});
        }else{
            if(arr[i]>curdn[at1]){

                at1++;
                curdn[at1] = arr[i];
                inddn[at1] = i;
                while(arr[i]<=adjdn[at1-1][reldn[at1-1]].first){
                    sumdn[at1-1]-=adjdn[at1-1][reldn[at1-1]].second;
                    if(sumdn[at1-1]<0)sumdn[at1-1]+=MOD;
                    reldn[at1-1]++;
                }
                dn[i] = at1;
                dnct[i] = sumdn[at1-1];
                adjdn[at1].pb({arr[i],dnct[i]});
                sumdn[at1]+=dnct[i];
            }else{
                int l = 1;
                int r = at1;
                while(l!=r){
                    int mid = (l+r)>>1;
                    if(curdn[mid]<arr[i]){
                        l = mid+1;
                    }else{
                        r = mid;
                    }
                }
                curdn[l] = arr[i];
                inddn[l] = i;
                dn[i] = l;
                if(l==1){
                    dnct[i] = 1;
                }else{
                    while(arr[i]<=adjdn[l-1][reldn[l-1]].first){
                        sumdn[l-1]-=adjdn[l-1][reldn[l-1]].second;
                        if(sumdn[l-1]<0)sumdn[l-1]+=MOD;
                        reldn[l-1]++;
                    }
                    dnct[i] = sumdn[l-1];
                }

                adjdn[l].pb({arr[i],dnct[i]});
                sumdn[l]+=dnct[i];
                if(sumdn[l]>=MOD)sumdn[l]-=MOD;
            }


        }
    }
    for(int i = n-1; i >=0; i--){
        if(i==n-1){
            curup[1] = arr[i];
            indup[1] = i;
            up[i] = 1;
            upct[i] = 1;
            sumup[1] = 1;
            adjup[1].pb({arr[i],1});
        }else{
            if(arr[i]<curup[at2]){

                at2++;
                curup[at2] = arr[i];
                indup[at2] = i;
                while(arr[i]>=adjup[at2-1][relup[at2-1]].first){
                    sumup[at2-1]-=adjup[at2-1][relup[at2-1]].second;
                    if(sumup[at2-1]<0)sumup[at2-1]+=MOD;
                    relup[at2-1]++;
                }
                up[i] = at2;
                upct[i] = sumup[at2-1];
                adjup[at2].pb({arr[i],upct[i]});
                sumup[at2]+=upct[i];
            }else{
                int l = 1;
                int r = at2;
                while(l!=r){
                    int mid = (l+r)>>1;
                    if(curup[mid]>arr[i]){
                        l = mid+1;
                    }else{
                        r = mid;
                    }
                }
                curup[l] = arr[i];
                indup[l] = i;
                up[i] = l;
                if(l==1){
                    upct[i] = 1;
                }else{
                    while(arr[i]>=adjup[l-1][relup[l-1]].first){
                        sumup[l-1]-=adjup[l-1][relup[l-1]].second;
                        if(sumup[l-1]<0)sumup[l-1]+=MOD;
                        relup[l-1]++;
                    }
                    upct[i] = sumup[l-1];
                }

                adjup[l].pb({arr[i],upct[i]});
                sumup[l]+=upct[i];
                if(sumup[l]>=MOD)sumup[l]-=MOD;
            }


        }
    }
    /*FORR1(n){
        cout<<dn[i]<<" "<<dnct[i]<<'\n';
    }
    cout<<"----\n";
    FORR1(n){
        cout<<up[i]<<" "<<upct[i]<<'\n';
    }*/
    int Max = 0;
    FORR1(n){
        Max = max(Max, up[i]+dn[i]-1);
    }
    int val = 1;
    for(int i = 0; i < n-Max; i++){
        val*=2;
        val%=MOD;
    }
    ll ans = 0;
    FORR1(n){
        if(up[i]+dn[i]-1==Max){
            ans+=(ll)upct[i]*dnct[i];
            ans%=MOD;
        }
    }
    cout<<Max<<" "<<ans*val%MOD<<'\n';



}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    //cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}
# 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 1 ms 340 KB Output is correct
11 Correct 42 ms 20620 KB Output is correct
12 Correct 35 ms 17984 KB Output is correct
13 Correct 31 ms 16960 KB Output is correct
14 Correct 43 ms 17096 KB Output is correct
15 Correct 54 ms 21428 KB Output is correct
16 Correct 64 ms 24636 KB Output is correct
17 Correct 63 ms 26796 KB Output is correct
18 Correct 74 ms 27084 KB Output is correct
19 Correct 62 ms 26900 KB Output is correct
20 Correct 65 ms 26912 KB Output is correct