2782021-06-22 15:25:47mraronMaximum felosztáscpp14Accepted 100/100266ms96216 KiB
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cassert>
#include<cassert>
#include<unordered_map>
#include<unordered_set>
#include<functional>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<sstream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<numeric>
#include<random>
#include<chrono>
#include<bitset>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define xx first
#define yy second
#define sz(x) (int)(x).size()
#define gc getchar
#define IO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define mp make_pair

#ifndef ONLINE_JUDGE
#  define LOG(x) (cerr << #x << " = " << (x) << endl)
#else
#  define LOG(x) ((void)0)
#endif

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const double PI=3.1415926535897932384626433832795;
const ll INF = 1LL<<62;
const ll MINF = -1LL<<62;

template<typename T> T getint() {
	T val=0;
	char c;
	
	bool neg=false;
	while((c=gc()) && !(c>='0' && c<='9')) {
		neg|=c=='-';
	}

	do {
		val=(val*10)+c-'0';
	} while((c=gc()) && (c>='0' && c<='9'));

	return val*(neg?-1:1);
}

//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); uniform_int_distribution<int>(0, n-1)(rng)

#define int ll

int n,m;

const int MAXN=100001;

int A[MAXN], B[MAXN];

const int mod = 1e9+7;
void modadd(int& a, int b) {
    a+=b;
    if(a>=mod) a-=mod;   
}

int nxt[MAXN];
int prv[MAXN];

void calc_nxt() {
    vector<int> stk;
    for(int i=n;i>=1;i--) {
        while(!stk.empty() && A[stk.back()]<A[i]) stk.pop_back();
        nxt[i]=stk.empty()?n+1:stk.back();
        stk.pb(i);
    }
}

void calc_prv() {
    vector<int> stk;
    for(int i=1;i<=n;i++) {
        while(!stk.empty() && A[stk.back()]<=A[i]) stk.pop_back();
        prv[i]=stk.empty()?0:stk.back();
        stk.pb(i);
    }
}

vector<int> val[2*MAXN];
int ind[2*MAXN];

pair<bool, int> operator+(pair<bool, int> a, pair<bool, int> b) {
    if(a.xx && b.xx) return b;
    if(a.xx && !b.xx) return {true, (a.yy+b.yy)%mod};
    if(!a.xx && b.xx) return b;
    if(!a.xx && !b.xx) return {false, (a.yy+b.yy)%mod};
}

struct segtree {
    segtree(int n_) : n(n_) {
        tr.resize(4*n);
        lazy.assign(4*n, mp(false, 0));
    }
    
    void point_set(int pt, int val) {
        point_set(1, 0, n-1, pt, val);
    }
    
    int get(int i) {
        return range_sum(i,i);
    }
    
    int range_sum(int L, int R) {
        return range_sum(1,0,n-1,L,R);
    }
    
    void range_incr(int L, int R, int by) {
        range_incr(1,0,n-1,L,R,by);
    }
    
    void clear() {
        lazy[1]={true, 0};
    }
    
    void print() {
        for(int i=0;i<n;++i) {
            cout<<get(i)<<" ";
        }cout<<"\n";
    }
private:
    int n;
    vector<int> tr;
    vector<pair<bool,int>> lazy;
    
    void pull(int ind, int L, int R) {
        if(L!=R) {
            tr[ind]=(tr[2*ind]+tr[2*ind+1])%mod;
        }
    }
    
    void push(int ind, int L, int R) {
        if(lazy[ind].xx==true || lazy[ind].yy!=0) {
            if(L!=R) {
                lazy[2*ind]=lazy[2*ind]+lazy[ind];
                lazy[2*ind+1]=lazy[2*ind+1]+lazy[ind];
            }
        }
        
        if(lazy[ind].xx==true) {
            tr[ind]=0;
            lazy[ind].xx=false;
        }
        
        if(lazy[ind].yy!=0) {
            tr[ind]+=(R-L+1)*lazy[ind].yy%mod;
            tr[ind]%=mod;
            
            lazy[ind].yy=0;
        }
    }
    
    void point_set(int ind, int L, int R, int i, int to) {
        push(ind, L, R);
        if(R<i || i<L) return ;
        if(L==R) {
            tr[ind]=to;
            return ;
        }
        
        point_set(2*ind, L, (L+R)/2, i, to);
        point_set(2*ind+1, (L+R)/2+1, R, i, to);
        
        pull(ind, L, R);
    }
    
    int range_sum(int ind, int L, int R, int i, int j) {
        push(ind, L, R);
        if(R<i || j<L) return 0;
        if(i<=L && R<=j) return tr[ind];
        
        return (range_sum(2*ind, L, (L+R)/2, i, j)+range_sum(2*ind+1, (L+R)/2+1, R, i, j))%mod;
    }
    
    void range_incr(int ind, int L, int R, int i, int j, int by) {
        push(ind, L, R);
        if(R<i || j<L) return ;
        if(i<=L && R<=j) {
            lazy[ind]={false, by};
            push(ind, L, R);
            return ;
        }
        
        range_incr(2*ind, L, (L+R)/2, i, j, by);
        range_incr(2*ind+1, (L+R)/2+1, R, i, j, by);
        
        pull(ind, L, R);
    }
};

main() {
    IO;
    
    cin>>n>>m;
    
    vector<int> srtd;
    
    for(int i=1;i<=n;++i) {
        cin>>A[i];
        srtd.pb(A[i]);
    }
    for(int j=1;j<=m;++j) {
        cin>>B[j];
        srtd.pb(B[j]);
    }
    
    sort(all(srtd));
    srtd.resize(distance(srtd.begin(), unique(all(srtd))));
    
    for(int i=1;i<=n;++i) {
        A[i]=lower_bound(all(srtd), A[i])-srtd.begin();
        if(i<=m) B[i]=lower_bound(all(srtd), B[i])-srtd.begin();
    }

    calc_nxt();
    calc_prv();
    
    for(int i=n;i>=1;--i) {
        val[A[i]].push_back(i);
    }
    
    segtree a(n+1);
    segtree b(n+1);
    a.point_set(0, 1);
    
    segtree& st=a;
    segtree& tmp=b;
    
    for(int i=1;i<=m;++i) {
        for(auto pos:val[B[i]]) {
            int s=st.range_sum(prv[pos], pos-1);
            tmp.range_incr(pos, nxt[pos]-1, s);
        }
        
        swap(st, tmp);
        tmp.clear();
    }
    
    cout<<(st.get(n))<<"\n";
    
    
    return 0;
}
SubtaskSumTestVerdictTimeMemory
subtask10/0
1Accepted6ms11260 KiB
2Accepted8ms12288 KiB
subtask210/10
3Accepted6ms11700 KiB
4Accepted6ms11720 KiB
5Accepted6ms11716 KiB
6Accepted6ms11724 KiB
7Accepted6ms11744 KiB
8Accepted6ms11744 KiB
subtask315/15
9Accepted6ms11756 KiB
10Accepted6ms11772 KiB
11Accepted6ms11772 KiB
12Accepted6ms11776 KiB
13Accepted6ms11792 KiB
14Accepted6ms11800 KiB
15Accepted6ms11816 KiB
16Accepted6ms11828 KiB
17Accepted6ms11840 KiB
18Accepted7ms11840 KiB
subtask415/15
19Accepted8ms12540 KiB
20Accepted8ms12556 KiB
21Accepted8ms12588 KiB
22Accepted7ms12464 KiB
23Accepted6ms12632 KiB
24Accepted7ms12584 KiB
25Accepted8ms12668 KiB
26Accepted8ms12700 KiB
27Accepted8ms12760 KiB
28Accepted8ms12804 KiB
29Accepted7ms12784 KiB
30Accepted6ms12668 KiB
31Accepted7ms12820 KiB
32Accepted7ms12848 KiB
33Accepted8ms12884 KiB
34Accepted7ms12916 KiB
35Accepted8ms12956 KiB
36Accepted7ms12988 KiB
37Accepted8ms12856 KiB
38Accepted7ms13028 KiB
subtask560/60
39Accepted180ms63528 KiB
40Accepted200ms62888 KiB
41Accepted194ms63944 KiB
42Accepted239ms63448 KiB
43Accepted266ms64352 KiB
44Accepted90ms68752 KiB
45Accepted167ms67684 KiB
46Accepted209ms68792 KiB
47Accepted158ms72092 KiB
48Accepted233ms71220 KiB
49Accepted165ms74516 KiB
50Accepted239ms74036 KiB
51Accepted144ms73972 KiB
52Accepted108ms76620 KiB
53Accepted97ms77724 KiB
54Accepted138ms75832 KiB
55Accepted114ms78364 KiB
56Accepted184ms80748 KiB
57Accepted246ms81968 KiB
58Accepted108ms84972 KiB
59Accepted133ms86196 KiB
60Accepted93ms84312 KiB
61Accepted89ms85268 KiB
62Accepted128ms86900 KiB
63Accepted128ms87432 KiB
64Accepted135ms89600 KiB
65Accepted136ms89816 KiB
66Accepted129ms92248 KiB
67Accepted96ms94884 KiB
68Accepted137ms93764 KiB
69Accepted115ms96216 KiB
70Accepted148ms94760 KiB
71Accepted138ms95772 KiB