E. Maximize Mex

传送门

题目

There are nn students and mm clubs in a college. The clubs are numbered from 11 to mm. Each student has a potential pipi and is a member of the club with index cici. Initially, each student is a member of exactly one club. A technical fest starts in the college, and it will run for the next dd days. There is a coding competition every day in the technical fest.

Every day, in the morning, exactly one student of the college leaves their club. Once a student leaves their club, they will never join any club again. Every day, in the afternoon, the director of the college will select one student from each club (in case some club has no members, nobody is selected from that club) to form a team for this day's coding competition. The strength of a team is the mex of potentials of the students in the team. The director wants to know the maximum possible strength of the team for each of the coming dddays. Thus, every day the director chooses such team, that the team strength is maximized.

The mex of the multiset SS is the smallest non-negative integer that is not present in SS. For example, the mex of the {0,1,1,2,4,5,9}{0,1,1,2,4,5,9} is 33, the mex of {1,2,3}{1,2,3} is 00 and the mex of ∅∅ (empty set) is 00.

Input

The first line contains two integers nn and mm (1≤m≤n≤50001≤m≤n≤5000), the number of students and the number of clubs in college.

The second line contains nn integers p1,p2,…,pnp1,p2,…,pn (0≤pi<50000≤pi<5000), where pipi is the potential of the ii-th student.

The third line contains nn integers c1,c2,…,cnc1,c2,…,cn (1≤ci≤m1≤ci≤m), which means that ii-th student is initially a member of the club with index cici.

The fourth line contains an integer dd (1≤d≤n1≤d≤n), number of days for which the director wants to know the maximum possible strength of the team.

Each of the next dd lines contains an integer kiki (1≤ki≤n1≤ki≤n), which means that kiki-th student lefts their club on the ii-th day. It is guaranteed, that the kiki-th student has not left their club earlier.

Output

For each of the dd days, print the maximum possible strength of the team on that day.

Examples

input

Copy

5 3
0 1 2 2 0
1 2 2 3 2
5
3
2
4
5
1

output

Copy

3
1
1
1
0

input

Copy

5 3
0 1 2 2 1
1 3 2 3 2
5
4
2
3
5
1

output

Copy

3
2
2
1
0

input

Copy

5 5
0 1 2 4 5
1 2 3 4 5
4
2
3
5
4

output

Copy

1
1
1
1

Note

Consider the first example:

On the first day, student 33 leaves their club. Now, the remaining students are 11, 22, 44 and 55. We can select students 11, 22 and 44 to get maximum possible strength, which is 33. Note, that we can't select students 11, 22 and 55, as students 22 and 55 belong to the same club. Also, we can't select students 11, 33 and 44, since student 33 has left their club.

On the second day, student 22 leaves their club. Now, the remaining students are 11, 44 and 55. We can select students 11, 44 and 55 to get maximum possible strength, which is 11.

On the third day, the remaining students are 11 and 55. We can select students 11 and 55 to get maximum possible strength, which is 11.

On the fourth day, the remaining student is 11. We can select student 11 to get maximum possible strength, which is 11.

On the fifth day, no club has students and so the maximum possible strength is 00.

题意:现在有n个学生m个俱乐部,每个学生都有一个潜力值,现在需要从m个俱乐部中各选出一个人,定义选出的人的值为从0开始的第一个没有出现过的数,每过一天会有一个俱乐部成员离开,问你每天选出的人的最大值为多少?

题解:每一个俱乐部都有一些潜力值,相应的潜力值就可以从对应俱乐部中选出,就可以将俱乐部与潜力值之间建一条边,如果不考虑删除操作,则从0开始跑二分匹配就可以得到当前答案,然后在考虑删除操作,如果每次二分匹配后删除对应的边,则删除的有可能是已经选过的边就需要重新跑匹配,则复杂度就就会接近n的3方,所以需要考虑其他方法然后考虑每天离开的人,离开后只会对后面几天的选择造成影响,则从后往前每天添加删除的人就避开删除操作,对于每个添加的人对答案有影响只会成为一个桥梁将答案往上顺延;

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#define ll long long
using namespace std;
const int maxn=5e3+5;
vector<int> v[maxn];
int p[maxn],c[maxn],k[maxn];
bool judge1[maxn],judge2[maxn];
int judge[maxn];
void init(){
    memset(judge,-1,sizeof(judge));
    memset(judge1,false,sizeof(judge1));
    memset(judge2,false,sizeof(judge2));
}
bool find1(int n){
    if(judge1[n])
        return false;
    judge1[n]=true;
    for(int a=0;a<v[n].size();a++){
        int b=v[n][a];
        if(judge[b]==-1||find1(judge[b])){
            judge[b]=n;
            return true;
        }
    }
    return false;
}
void add(int a){
    v[p[a]].push_back(c[a]);
}
int ans[maxn];
int main( ){
    init();
    int n,m;
    scanf("%d %d",&n,&m);
    for(int a=1;a<=n;a++)
        scanf("%d",&p[a]);
    for(int a=1;a<=n;a++)
        scanf("%d",&c[a]);
    int d;
    scanf("%d",&d);
    for(int a=1;a<=d;a++){
        scanf("%d",&k[a]);
        judge2[k[a]]=true;
    }
    for(int a=1;a<=n;a++){
        if(!judge2[a]){
            v[p[a]].push_back(c[a]);
        }
    }
    int t=0;
    for(int a=d;a>=1;a--){
        memset(judge1,false,sizeof(judge1));
        while(find1(t)){
            t++;
            memset(judge1,false,sizeof(judge1));
        }
        ans[a]=t;
        add(k[a]);
    }
    for(int a=1;a<=d;a++)
        printf("%d\n",ans[a]);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值