G Greater and Greater
Description
Given a sequence A of size n{n}n and a sequence B of size m, determine the number of subintervals(called S) of size m in A satisfying ∀i∈{1,2,⋯,m},Si≥Bi.
Input
The first line contains two integers n,m (1≤n≤150000,1≤m≤min{n,40000}).
The second line contains n integers A1,A2,⋯,An (1≤Ai≤109), denoting the sequence A.
The third line contains n{n}n integers B1,B2,⋯,Bn (1≤Bi≤109), denoting the sequence B.
Output
Only one line containing one integer, denoting the answer.
Samples
Input 复制
6 3
1 4 2 8 5 7
2 3 3
Output
2
Hint
The two subintervals are [2,8,5],[8,5,7].
Source
2020牛客-2
题意:给你一个序列A,让你从A中找出一个些子串S,让串S对应位置Si上的元素大于等于Bi,问一共可以找出多少个这种的序列
思路:这是个考二进制的好题,第一步的转换就不好想。
首先判断A序列中的每个元素是否比B中的元素大,比B中的元素大即为一,否者为0
例如:
A:1 4 2 8 5 7
B:2 3 3
B[1] = 2 : 0 1 1 1 1 1
B[2] = 3 : 0 1 0 1 1 1
B[3] = 3 : 0 1 0 1 1 1
这一步转换就很妙了,因为我们可以发现只要有一条斜线全为1,那么此子串就是一个答案,但是我们这样求复杂度为O(n*m),我们可以将序列A,B排序,将复杂度降为O(n),我们从排序后的第一个数字开始算,那么如果比最大数字(B[1])还要大,那一定也比B[1]小的数字大
从此图可以看出(A[3],A[4],A[5])和(A[4],A[5],A[6])这两个串即为所求;
最后我们将每个数的二进制进行移位,具体操作如下:
B[1] = 2 : 0 1 1 1 1 1 左移零位
B[2] = 3 : 1 0 1 1 1 0 左移一位
B[3] = 3 : 0 1 1 1 0 0 左移两位
然后我们每一列都与1做&运算,最后看有几个一即可;
bitset:
bitset<N> test,tep;//创建N位的二进制位,默认值为零
test.set();//将所有位都置为一
test.set(i);//将第i位置为一
test.count();//1的个数
test&tep;//test与tep按位与
test<<i;//test左移i位,右面补零
Code:
#include<bits/stdc++.h>
#define bug(x) cout<<#x<<" = "<<x<<endl;
using namespace std;
typedef long long ll;
const int N = 1e5 + 5e4 +10;
const int inf = 1e9;
bitset<N>ans,bs;
vector<pair<int,int> >a,b;
int n,m,p;
bool cmp(pair<int,int> x,pair<int,int> y) {
return x.first > y.first;
}
int main() {
cin>>n>>m;
int x;
for(int i=0; i<n; i++) {
cin>>x;
a.push_back({x,i});
}
for(int i=0; i<m; i++) {
cin>>x;
b.push_back({x,i});
}
sort(a.begin(),a.end(),cmp);
sort(b.begin(),b.end(),cmp);
ans.set();
int j = 0;
for(int i=0; i<m; i++) {
while(j<n&&a[j].first>=b[i].first) {
bs.set(a[j].second);
j++;
}
// for(int k=0;k<n;k++) cout<<bs[k]<<" ";
// putchar('\n');
ans&=bs>>b[i].second;
}
printf("%d",ans.count());
return 0;
}