Description
Last time, the king of the country Qi lost to Tian Ji in a horse race as Tian using a little trick. Today, the king invites Tian to play another horse race. The king and Tian both have n horses, and no two horses have the same speed. They will play n rounds in this match. The horses on each side must appear in descending order of speed, and each of the horses must be used in one round. The horse with a faster speed will win in a single round. Since Tian’s horses are not so nice as the king’s, the king allows Tian to exchange some horses with him.
If Tian can exchange at most k horses with the king, what is the maximum number of rounds that Tian can win?
Input
There will be at most 200 test cases. Each case begins with two integers n, m(1 ≤ m ≤ n ≤ 105), the number of horses on each side and the number of queries. The next line contains n positive integers, denoting the speeds of king's horses in descending order. Then the following line contains n positive integers, denoting the speeds of Tian's horses in descending order. The speed of each horse will not exceed 106, and no two horses have the same speed. The queries are defined by the following m lines, and each line contains one integer k(0 ≤ k < n). The size of the whole input file does not exceed 10MB.
Output
For each query, print the maximum number of rounds that Tian can win, when he can exchange at most k horses with the king.
Sample Input
4 3
8 7 6 4
5 3 2 1
0
2
1
3 1
7 3 2
8 6 5
0
Sample Output
0
4
2
3
Hint
Source
湖南省第十三届大学生计算机程序设计竞赛
题目大意:以降序的形式给出齐王的马的速度和田忌的马的速度,保证任意两匹马的速度都不一样。对于每个询问
k
k
k,若齐王和田忌至多可交换
k
k
k匹马,输出田忌最多的胜场数。齐王和田忌的马的出场顺序是按照速度降序的。
思路:根据贪心思想,我们肯定拿齐王跑的最快的马和田忌最慢的马交换。我们考虑交换齐王的第
i
i
i匹马和田忌的第
j
j
j匹马,那么这匹马应该插入的位置
p
o
s
pos
pos满足
b
[
p
o
s
−
1
]
>
a
[
i
]
>
b
[
p
o
s
]
b[pos-1]>a[i]>b[pos]
b[pos−1]>a[i]>b[pos],此时易证对于任意的
x
<
=
p
o
s
x<=pos
x<=pos,均有
b
[
x
]
>
a
[
x
]
b[x]>a[x]
b[x]>a[x],仔细思考一下,其实把这匹马插到序列
b
b
b的头部,依然满足这个条件。同理可知田忌的马也可插到序列
a
a
a的尾部。因此每次交换,相当于把序列
b
b
b向后推了一步,把序列
a
a
a向前推了一步。如果我们有一个数组
p
o
s
pos
pos对于序列
b
b
b的第
i
i
i个元素满足
a
[
i
+
p
o
s
[
i
]
−
1
]
>
b
[
i
]
>
a
[
i
+
p
o
s
[
i
]
]
a[i+pos[i]-1]>b[i]>a[i+pos[i]]
a[i+pos[i]−1]>b[i]>a[i+pos[i]],若此时可以交换
(
p
o
s
[
i
]
+
1
)
/
2
(pos[i]+1)/2
(pos[i]+1)/2次,那么序列
a
a
a向前推进,序列
b
b
b向后推进,此时
b
b
b的第
i
i
i个元素一定可以给答案贡献
1
1
1。那么这题的思路就很明显了:处理出
p
o
s
pos
pos数组后进行计数+前缀和操作。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+5;
int n,m;
int a[maxn],b[maxn],pos[maxn],sum[maxn];
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
a[n+1]=0;
int p=1;
for(int i=1;i<=n;i++)
{
while(a[p]>b[i])
++p;
pos[i]=max(p-i,0);
}
for(int i=1;i<=n;i++)
sum[(pos[i]+1)/2]++;
for(int i=1;i<=n;i++)
sum[i]+=sum[i-1];
int k;
for(int i=0;i<m;i++)
{
scanf("%d",&k);
printf("%d\n",sum[k]);
}
}
return 0;
}
/**********************************************************************
Problem: 2000
User: xijixiji
Language: C++
Result: AC
Time:508 ms
Memory:3584 kb
**********************************************************************/