G Greater and Greater(求满足条件的子序列,bitset用法)

题:https://ac.nowcoder.com/acm/contest/5667/G

题意:给定n个数的数组A,m个数的数组B,问在A中有多少个子数组满足Si>=Bi

分析:我们可以考虑记录合法子数组以数组A中的一个位置代表一个合法子数组(因为长度固定为m);

   设bitset  的ans和tmp,其中tmp为1的位置表示,对于当前的bi ,a数组中有哪些比b[i].val大;

   如果某个位置x比当前的b[i].val大于等于,那么x-b[i].id的位置就可能形成一个合法序列;

   最后答案就是要找出这些所有的开头(即ans中1的个数

   等价于tmp中1的位置向右移动b[i].id位

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
typedef long long ll;
const int mod=998244353;
const int M=150005;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
bitset<150002>ans,tmp;
struct node{
    int val,id;
}a[M],b[M];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].val),a[i].id=i;
    for(int i=1;i<=m;i++)
        scanf("%d",&b[i].val),b[i].id=i;
    sort(a+1,a+1+n,[&](node A,node B){
        return A.val>B.val;
    });
    sort(b+1,b+1+m,[&](node A,node B){
        return A.val>B.val;
    });
    ans.set();///初始全1
    int nowi=1;
    for(int i=1;i<=m;i++){
        while(nowi<=n&&a[nowi].val>=b[i].val){
            tmp.set(a[nowi].id);
            nowi++;
        }
        ans&=(tmp>>b[i].id);
    }
    printf("%d
",ans.count());
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/starve/p/13299618.html