题目描述 宿管有一套神奇的控制系统来控制寝室的灯的开关:
共有N盏灯,标号为1到N,有M个标有不同质数的开关,开关可以控制所有标号为其标号倍数的灯,按一次开关,所有其控制的灭着的灯都点亮,所有其控制的亮着的灯将熄灭。现在,宿管可以无限的按所有开关,所有灯初始状态为熄灭,请求出最多能点亮几盏灯。
输入 输入有多组数据,第一行一个正整数T表示数据组数。 每组数据第一行两个整数N,M。
第二行M个不同的质数表示开关上的标号,保证所有标号<=N。 输出 对于每组数据输出一行一个整数表示最多亮灯数。样例输入
4
10 2
2 5
21 4
2 3 5 7
100 1
5
100
3
3 19 7
样例输出
5 11 20 42
提示
对于50%的数据,N<=15;对于100%的数据,T<=10,N<=1000。
分块思想。大于sqrt(1000) 的质数不会互相干扰。而小于sqrt(1000)的质数也就13个(吧)。所以我们只要2^13次方暴力枚举所有可能,再贪心地加质数就好了。
var
na,nb,ans,i,n,m,t,x:longint;
a,b,f:array[0..1011] of longint;
flag:array[0..1011] of boolean;
procedure add(u:longint);
var
i:longint;
begin
i:=u;
while i<=n do
begin
if flag[i]=false then flag[i]:=true
else flag[i]:=false;
i:=i+u;
end;
end;
procedure check;
var
s,i,j,num1,num2:longint;
begin
fillchar(flag,sizeof(flag),false);
for i:=1 to na do
if f[i]=1 then
add(a[i]);
for i:=1 to nb do
begin
num1:=0;
num2:=0;
j:=b[i];
while j<=n do
begin
if flag[j]=false then num1:=num1+1
else num2:=num2+1;
j:=j+b[i];
end;
if num1>num2 then
add(b[i]);
end;
s:=0;
for i:=1 to n do
if flag[i] then s:=s+1;
if s>ans then ans:=s;
end;
procedure dfs(i:longint);
begin
if i>na then begin check; exit; end;
f[i]:=0;
dfs(i+1);
f[i]:=1;
dfs(i+1);
end;
begin
readln(t);
while t>0 do
begin
na:=0;
nb:=0;
ans:=0;
t:=t-1;
readln(n,m);
for i:=1 to m do
begin
read(x);
if x<trunc(sqrt(n)) then
begin
na:=na+1;
a[na]:=x;
end
else
begin
nb:=nb+1;
b[nb]:=x;
end;
end;
readln;
dfs(1);
writeln(ans);
end;
end.