2020牛客暑期多校訓練營(第二場)G-Greater and Greater bitset
阿新 • • 發佈:2020-07-14
題意
給一個大小為\(n\)的序列\(A\)和一個大小為\(m\)的序列\(B\),問\(A\)中有多少大小為\(m\)的子段\(S\)滿足\(\forall i\in \{1,2,\dots,m \},S_i\ge B_i\)。
分析
對\(A\)中每個位置開一個\(bitset<m>g\) 記錄\(B\)中哪些位置是滿足條件的,就可以通過位運算\(s=(g_i>>1\& s)<<1\)來轉移得到當前\(A\)中第\(i\)位能匹配到\(B\)中哪些位置,如果\(s[m]==1\),表示找到了一個子段滿足條件。對\(A\)的每個位置開\(bitset\)
Code
#include<algorithm> #include<iostream> #include<cstring> #include<iomanip> #include<sstream> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define rep(i,x,n) for(int i=x;i<=n;i++) #define per(i,n,x) for(int i=n;i>=x;i--) #define sz(a) int(a.size()) #define rson mid+1,r,p<<1|1 #define pii pair<int,int> #define lson l,mid,p<<1 #define ll long long #define pb push_back #define mp make_pair #define se second #define fi first using namespace std; const double eps=1e-8; const int mod=1e9+7; const int N=1e5+10; const int inf=1e9; int n,m; int a[N],b[N],c[N],d[N],pos[N],tot; bitset<40010>g[40010]; int main(){ //ios::sync_with_stdio(false); //freopen("in","r",stdin); scanf("%d%d",&n,&m); rep(i,1,n){ scanf("%d",&a[i]); c[i]=i; } rep(i,1,m){ scanf("%d",&b[i]); d[i]=i; } sort(c+1,c+n+1,[](int x,int y){return a[x]<a[y];}); sort(d+1,d+m+1,[](int x,int y){return b[x]<b[y];}); int now=1; bitset<40010>pig; g[0]=pig; rep(i,1,n){ int flag=0; while(a[c[i]]>=b[d[now]]&&now<=m){ pig.set(d[now++]); flag=1; } if(flag) g[++tot]=pig; pos[c[i]]=tot; } bitset<40010>s; s.set(0); int ans=0; rep(i,1,n){ s=(g[pos[i]]>>1&s)<<1; if(s[m]) ans++; s.set(0); } printf("%d\n",ans); return 0; }