1366E. Two Arrays——(组合数学)

    技术2024-03-21  87

    题意

    给出一个长度为 n 的序列 a ,再给出一个长度为 m 的序列 b ,题目保证序列 b 是严格递增的,我们需要将 a 分割成恰好 m 段,使得每一段的最小值恰好等于 b[ i ] ,问有多少种分割方法

    解析

    出发点 bi<bi+1,说明数组b是严格递增的 侧面说明bi为后缀min 利用 bi为a数组某一段区间,且区间最小值为 bi ; 这个区间的左端点的后缀min为 bi ,说明bi的区间左端点的后缀min为 bi 。 所以每个 bi 区间可能性为后缀 min= =b[i] 的个数,右端点不用考虑,然后累成原理

    题目链接

    //#pragma GCC optimize(2) //#pragma GCC target ("sse4") #include<bits/stdc++.h> //typedef long long ll; #define ull unsigned long long #define int long long #define F first #define S second #define endl "\n"//<<flush #define eps 1e-6 #define base 131 #define lowbit(x) (x&(-x)) #define PI acos(-1.0) #define inf 0x3f3f3f3f #define MAXN 0x7fffffff #define INF 0x3f3f3f3f3f3f3f3f #define ferma(a,b) pow(a,b-2) #define mod(x) (x%mod+mod)%mod #define pb push_back #define decimal(x) cout << fixed << setprecision(x); #define all(x) x.begin(),x.end() #define rall(x) x.rbegin(),x.rend() #define memset(a,b) memset(a,b,sizeof(a)); #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; template<typename T> inline T fetch(){T ret;cin >> ret;return ret;} template<typename T> inline vector<T> fetch_vec(int sz){vector<T> ret(sz);for(auto& it: ret)cin >> it;return ret;} template<typename T> inline void makeUnique(vector<T>& v){sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());} void file() { #ifdef ONLINE_JUDGE #else freopen("D:/LSNU/codeforces/duipai/data.txt","r",stdin); // freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout); #endif } const int N=2e5+5; const int mod=998244353; int a[N],b[N],suf[N]; signed main() { IOS; file(); int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) cin>>b[i]; suf[n+1]=inf; map<int,int>ma; for(int i=n;i>=1;i--) suf[i]=min(suf[i+1],a[i]),ma[suf[i]]++; int ans=1; for(int i=2;i<=m;i++) ans=ans*ma[b[i]]%mod; cout<<(suf[1]==b[1]?ans:0)<<endl; return 0; }
    Processed: 0.008, SQL: 9