Educational Codeforces Round 89 (Rated for Div. 2) 参与排名人数13281
[codeforces 1366E] Two Arrays 双指针+乘法原理+注意边界处理
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址http://codeforces.com/contest/1366/problem/E
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
E - Two Arrays | GNU C++17 | Accepted | 93 ms | 1800 KB |
做完该题,突然发现快速排序是双指针的鼻祖。
题目大意:将数组a中的连续元素分成m个子数组,要求第1个子数组中的最小值等于b1,第2个子数组中的最小值等于b2,
第3个子数组中的最小值等于b3,依次类推。问满足这种情况的分组,有几种可能。
样例进一步说明如下
6 3
12 10 20 20 25 30
10 20 30
2
第1种情况如下
[12,10,20],[20,25],[30]
[12,10,20]最小值是10,b[1]=10,两者相等
[20,25]最小值是20,b[2]=20,两者相等
[30]最小值是30,b[3]=30,两者相等
第2种情况如下
[12,10],[20,20,25],[30]
[12,10]最小值是10,b[1]=10,两者相等
[20,20,25]最小值是20,b[2]=20,两者相等
[30]最小值是30,b[3]=30,两者相等.
以下样例处理,可结合代码进行研究
样例1处理如下
6 3
12 10 20 20 25 30
10 20 30
2
ans=1;
b数组位置1 2 3
b数组数值10 20 30
a数组位置1 2 3 4 5 6
a数组数值12 10 20 20 25 30
逆向搜索
1.处理b[3]
a[6]==b[3],r=6
a[5]<b[3],l=5
乘法原理ans=1*(6-5)=1
2.处理b[2]
a[4]==b[2],r=4
a[2]<b[2],l=2
乘法原理ans=1*(4-2)=2
3.处理b[1]
a[2]==b[1],r=2
a[0]<b[1],l=0
此时没有选择,所有数据都必须归属于地一个分组。
综上所述,结果是2
样例2处理如下
4 2
1 3 3 7
3 7
0
ans=1;
b数组位置1 2
b数组数值3 7
a数组位置1 2 3 4
a数组数值1 3 3 7
逆向搜索
1.处理b[2]
a[4]==b[2],r=4
a[3]<b[2],l=3
乘法原理ans=1*(4-3)=1
2.处理b[1]
a[3]==b[1],r=4
a[1]<b[1],l=1
因为是第1个分组,还有a[1]元素选不进分组,故分组不存在
综上所述,结果是0
样例3处理如下
8 2
1 2 2 2 2 2 2 2
1 2
7
ans=1;
b数组位置1 2
b数组数值1 2
a数组位置1 2 3 4 5 6 7 8
a数组数值1 2 2 2 2 2 2 2
逆向搜索
1.处理b[2]
a[8]==b[2],r=8
a[1]<b[2],l=1
乘法原理ans=1*(8-1)=7
2.处理b[1]
a[1]==b[1],r=1
a[0]<b[1],l=0
此时没有选择,所有数据都必须归属于地一个分组。
综上所述,结果是7
AC代码如下
#include <stdio.h>
#define maxn 200010
#define mod 998244353
#define LL long long
int a[maxn],b[maxn],n,m;
LL ans=1;
int main(){
int i,j,l,r;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(i=1;i<=m;i++)scanf("%d",&b[i]);
r=n;
for(i=m;i>=1;i--){//逆向分组
while(a[r]>b[i])r--;//循环结束时,要么a[r]==b[i];要么a[r]<b[i];要么r==0;注意
if(a[r]!=b[i]||r==0){ans=0;break;}//表示没找到b[i]
l=r;
while(a[l]>=b[i])l--;//循环结束时要么a[l]<b[i];要么l==0;注意
if(i!=1)ans=ans*(r-l)%mod;//不是第1个分组时,乘法原理,区间[l+1,r] 个数r-(l+1)+1=r-l
else if(l!=0)ans=0;//i==1
r=l;//r是正宗右边界
}
printf("%lld\n",ans);
return 0;
}