There is a class consisting of n students, in which each one has a number representing his/her personality. The teacher gives the students a new assignment and asks them to solve it in groups so that each group can contain two students at most.

Students cannot create groups as they please because the teacher gives the following rules that must be met in order for a group to be valid:

  • The group can be‎由‎of one male student, one female student, or male and female students.
  • If the number of students in the group is two, these students must share common interests. Two students i and j share interests if and only if their numbers ai and aj share common divisor d > 1.

Since this is a really diverse class, no triple of students share a common interest, therefore all triples ai, aj, ak are co-primes (i.e. gcd(ai, aj, ak) ≡ 1).

Your task is to distribute the students into groups such that each student must join exactly one group, and the number of groups is as minimal as possible. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 100), in which T is the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 104), in which n is the number of students in the class.

Then a line follows containing n integers a1, a2, ..., an (1 ≤ ai ≤ 106), in which ai if the personality of the ith student. Then a line follows containing n space-separated characters p1, p2, ..., pn (), in which pi is "M" if the ith student is male, and "F" if she is female.

‎ ‎‎n‎‎ ‎‎总测试用例的总和不超过‎ 3 × 105.

Output

For each test case, print a single line containing the minimum number of groups that can be formed in the class.

Example

Input
2
2
3 6
M F
5
5 6 7 10 21
F F F M M
Output
1
3

Note

In the second test case, the minimum number of groups is 3, in which the first group consists of the 1st and 4th students, the second group consists of the 2nd student, and the third group consists of the 3rd and 5th students.

思路:第一反应是二分图匹配找到最大匹配数,再看数据n有1e4,而且T有1e2,用匈牙利可能会超时,所以用网络流写法;再思考如何建图连边,暴力n²会超时,只能想如何优化建边了。

想到题目要求两人gcd > 1,所以把每个人对应的数字拆分质因数,我这里先将女生的数的质因数通过df函数(作用就是得出该数的所有质因数且不记录重复的质因数)放入vector数组k[素数(质因数)][i]=女生对应的编号,在通过同样意义的df'数组将男生的数分解质因数,此时不用保存在数组里了,可以直接吧有该质因数的vector数组里的女生连边。

这样就能建图然后利用网络流跑一遍最大匹配,用总数减去最大匹配数得到结果了。

注:vector数组k[素数][i]里的素数并不是直接对应的素数,因为a[i]最大有1e6,所以直接存会很浪费空间,于是首先用素数筛将素数全部找出并标号,k[i][j]的第一维表示的是第i个素数。

贴一发优化llw大佬后的代码

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<stack> using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P; #define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define mid (l+r)/2
#define chl 2*k+1
#define chr 2*k+2
#define lson l,mid,chl
#define rson mid,r,chr
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a)); const long long mod=;
const int maxn=1e6+;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-;
const double pi=acos(-); struct edge {
int to,cap,rev;
};
vector <edge> G[maxn];
int level[maxn];
int iter[maxn]; void init(int _n) {
for(int i=; i<=_n; i++) {
G[i].clear();
}
} void bfs(int s) {
memset(level,-,sizeof(level));
queue<int> que;
level[s]=;
que.push(s);
while(!que.empty()) {
int v= que.front();
que.pop();
for(int i=; i<G[v].size(); i++) {
edge & e=G[v][i];
if(e.cap>&&level[e.to]<) {
level[e.to]=level[v] + ;
que.push(e.to);
}
}
}
} void add(int from,int to,int cap) {
edge eg;
eg.to=to;
eg.cap=cap;
eg.rev=G[to].size();
G[from].push_back(eg);
eg.to=from;
eg.cap=;
eg.rev=G[from].size()-;
G[to].push_back(eg);
} int dfs(int v,int t,int f) {
if(v == t)return f;
for(int &i = iter[v]; i < G[v].size(); i++) {
edge &e=G[v][i];
if(e.cap> && level[v]<level[e.to]) {
int d=dfs(e.to,t,min(f,e.cap));
if(d>) {
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
}
int maxflow(int s,int t) {
int flow=;
for(;;) {
bfs(s);
if(level[t]<)return flow;
memset(iter,,sizeof(iter));
int f;
while((f = dfs(s,t,INF))>) {
flow +=f;
}
}
} int a[maxn],b[maxn];
int prime[maxn];//存这是第几个素数
vector<int> v;//存素数
void sieve(int _n) {
int tot=;
memset(prime,,sizeof(prime));
prime[]=-;
prime[]=-;
for(int i=; i<=_n; i++) {
if (prime[i]==) {
prime[i]=tot++;
v.push_back(i);
for(int j=i*; j<=_n; j+=i) {
prime[j]=-;
}
}
}
} vector<int> k[maxn/];//大概估计一下区间内素数个数不足总数1/10 void df(int x,int pos) {//x为本身的数,pos为标号
if(x==)return;//1与任何数gcd都是1所以直接不考虑
for(int i=; i<v.size(); i++) {
if(x<v[i]) {//任何数的质因数肯定小于等于本身,大于就return了
return ;
}
if(prime[x]!=-) {//为素数
k[prime[x]].push_back(pos);
return ;
}
if(x%v[i]==)k[i].push_back(pos);//如果是合数就判断当前枚举素数是不是该合数的质因数
while(x%v[i]==) {//去掉重复质因数
x/=v[i];
}
}
}
void df2(int x,int pos) {
if(x==)return;
for(int i=; i<v.size(); i++) {
if(x<v[i]) {
return ;
}
if(prime[x]!=-) {
i=prime[x];
for(int j=; j<k[i].size(); j++) {//与有相同质因数的女生全部连边
add(k[i][j],pos,);
}
return ;
}
if(x%v[i]==) {
for(int j=; j<k[i].size(); j++) {//同上
add(k[i][j],pos,);
}
}
while(x%v[i]==) {
x/=v[i];
}
}
} int main() {
sieve(1e6+);//预处理素数筛
int t,n;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=; i<v.size(); i++) {
k[i].clear();
}
for(int i=; i<=n; i++) {
scanf("%d",&a[i]);
}
for(int i=; i<=n; i++) {
char s[];
scanf("%s",s);
if(s[]=='F') {
b[i]=;//女1男0
} else b[i]=;
}
init(n+);
for(int i=; i<=n; i++) {
if(b[i]==) {
df(a[i],i);
}
}
for(int i=; i<=n; i++) {
if(b[i]==) {
df2(a[i],i);
}
}
for(int i=; i<=n; i++) { if(b[i]==) {
add(,i,);
} else add(i,n+,);
}
printf("%d\n",n-maxflow(,n+));
}
return ;
}

CodeFroces New Assignment 二分图匹配的更多相关文章

  1. UVA 12549 - 二分图匹配

    题意:给定一个Y行X列的网格,网格种有重要位置和障碍物.要求用最少的机器人看守所有重要的位置,每个机器人放在一个格子里,面朝上下左右四个方向之一发出激光直到射到障碍物为止,沿途都是看守范围.机器人不会 ...

  2. POJ 1274 裸二分图匹配

    题意:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶,告诉每头奶牛愿意产奶的牛棚编号,求出最多能分配到的牛栏的数量. 分析:直接二分图匹配: #include<stdio.h> #includ ...

  3. BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2375  Solved: 1005[Submit][Sta ...

  4. HDU1281-棋盘游戏-二分图匹配

    先跑一个二分图匹配,然后一一删去匹配上的边,看能不能达到最大匹配数,不能这条边就是重要边 /*----------------------------------------------------- ...

  5. HDU 1083 网络流之二分图匹配

    http://acm.hdu.edu.cn/showproblem.php?pid=1083 二分图匹配用得很多 这道题只需要简化的二分匹配 #include<iostream> #inc ...

  6. hdu 5727 Necklace dfs+二分图匹配

    Necklace/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5727 Description SJX has 2*N mag ...

  7. BZOJ 1059 & 二分图匹配

    题意: 判断一个黑白染色的棋盘能否通过交换行或列使对角线上都是黑色. SOL: 真是有点醉...这种问题要么很神要么很水...第一眼感觉很水但就是不造怎么做...想了10分钟怎么感觉就是判断个数够不够 ...

  8. 【POJ 3020】Antenna Placement(二分图匹配)

    相当于用1*2的板覆盖给定的h*w的格子里的点,求最少的板.可以把格子相邻的分成两个集合,如下图,0为一个集合,1的为一个,也就是(行数+列数)为奇数的是一个集合,为偶数的为另一个集合.1010101 ...

  9. BZOJ-1143&&BZOJ-2718 祭祀river&&毕业旅行 最长反链(Floyed传递闭包+二分图匹配)

    蛋蛋安利的双倍经验题 1143: [CTSC2008]祭祀river Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1901 Solved: 951 ...

随机推荐

  1. [Algo] 118. Array Deduplication IV

    Given an unsorted integer array, remove adjacent duplicate elements repeatedly, from left to right. ...

  2. 1. Ruby基础知识

    1. Ruby执行选项 符号 作用 -c 检查代码正确性 -w 警告模式运行 -e 字面脚本 -l 行模式运行 单独 ruby -c Hello.rb 组合 ruby -le 'print " ...

  3. Oracle连接Navicat Premium遇到的问题

      ORA-28040: 没有匹配的验证协议. 通过查找资料找到了好的解决方案.可以不需要到官网上下载新的驱动来解决问题.    方法:在Oracle的安装路径下找到sqlnet.ora文件.(我的安 ...

  4. Dynamics CRM - Plug-in Class 和 Workflow Class 的用法与区别

    在 Dynamics CRM 开发中,我们可以使用 JavaScript 在前端对 Entity Form 进行数据操作,与此同时,我们也可以使用 C# 写后台插件,其中就包括了 Plug-in Cl ...

  5. Openstack 使用Centos官方镜像创建实例记录

    Openstack 使用Centos官方镜像创建实例记录 准备centos镜像 官方地址:http://cloud.centos.org/centos/7/images 可以看到有各种版本的镜像,我在 ...

  6. views层回顾

    目录 views层回顾 jsonResponse 2 大文件上传 3. cbv和fbv源码分析 4settings.py源码分析 5模板传值{{}} {%%} 6. 过滤器和标签和自定义 7模板的继承 ...

  7. Python这五个坑,80%你不知道(对的,五个你知道1个就达到一般水平了)

    1 含单个元素的元组 Python中有些函数的参数类型为元组,其内有1个元素,这样创建是错误的: c = (5) # NO! 它实际创建一个整型元素5,必须要在元素后加一个逗号: ! c = (5,) ...

  8. BTree非递归

    preorder void PreOrder(BTNode* b) { BTNode* p = b; SqStack* st; InitStack(st); if (b != NULL) { Push ...

  9. [单调队列]XKC's basketball team

    XKC's basketball team 题意:给定一个序列,从每一个数后面比它大至少 \(m\) 的数中求出与它之间最大的距离.如果没有则为 \(-1\). 题解:从后向前维护一个递增的队列,从后 ...

  10. linux4.11内核设备编译时出现的问题(参考博客并更改的)

    AllWinnerH3 linux4.11版本的bsp下载: https://pan.baidu.com/s/1mhU4a8K 密码: b375 H3-linux4.11_bsp目录就是所需的源码及编 ...