まず、答えに影響を与えずに、すべてのデジタル素因数インデックスを1に設定します。
元の画像Gの補数を考慮して、与えられたn個の数値のf [i]がiの倍数であることをf [i]に示します。したがって、各ポイントについて、許容度と除外の原則を使用して次数を計算できます(つまり、元の配列のgcd = 1の数。たとえば、ポイント1の重みは6で、次にdeg [1] = n- (f [2] + f [3] -f [6])。
点Fが見つかれば、deg [F]> 1にして、エッジのない2つの点をGとHとします。上記3点を削除した後、2つのケースで議論します。
A:次数> 0のk-3ポイントが少なくともあり、最小のmは二分法によって検出されるため、最初のmポイントで構成されるグラフでは、次数> 0のk-3ポイントがまだあります。ディスカッションを強力に分類し、mポイントのエッジのみを持つ部分を削除し、必要に応じてF、G、Hを回答に追加します(詳細はコードを参照してください)。
B:2k <= nであるため、次数> 0のk-3ポイントはありません。少なくとも次数0のkポイントがあり、任意のkポイントを選択できます(重みは2または2 gcd> 1)。
点Fが見つからない場合、図の接続されたブロックのサイズは3未満であり、接続された各ブロックの点を選択して回答に追加できます。
代码:
`` `cpp
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
`` `cpp
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n、k、t;
int pcnt = 0、pri [100000];
bool isp [1000000];
void getprime(void)
{
memset(isp、1、sizeof(isp));
for(int i = 2; i <1000000; i ++)
if(isp [i]){
pri [pcnt ++] = i;
for(int j = 2; i * j <1000000; j ++)
isp [i * j] = 0;
}
return;
}
int pcnt = 0、pri [100000];
bool isp [1000000];
void getprime(void)
{
memset(isp、1、sizeof(isp));
for(int i = 2; i <1000000; i ++)
if(isp [i]){
pri [pcnt ++] = i;
for(int j = 2; i * j <1000000; j ++)
isp [i * j] = 0;
}
return;
}
struct num {
int fac [10]、cnt;
} arr [100000];
int f [10000000];
void add(int i、int pos、int S)
{
if(pos == arr [i] .cnt){
if(S!= 1)f [S] ++;
戻る;
}
add(i、pos + 1、S);
add(i、pos + 1、S * arr [i] .fac [pos]);
戻る;
}
void del(int i、int pos、int S)
{
if(pos == arr [i] .cnt){
if(S!= 1)f [S]-;
戻る;
}
del(i、pos + 1、S);
del(i、pos + 1、S * arr [i] .fac [pos]);
戻る;
}
void read(void)
{
scanf( "%d%d"、&n、&k);
for(int i = 0; i <n; i ++){
scanf( "%d"、&t);
arr [i] .cnt = 0;
for(int j = 0; pri [j] * pri [j] <= t; j ++)
if(t%pri [j] == 0){
arr [i] .fac [arr [i] .cnt ++] = pri [j];
while(t%pri [j] == 0)
t / = pri [j];
}
if(t> 1)arr [i] .fac [arr [i] .cnt ++] = t;
if(i <2 * k)add(i、0,1);
}
n = 2 * k;
戻る;
}
int fac [10]、cnt;
} arr [100000];
int f [10000000];
void add(int i、int pos、int S)
{
if(pos == arr [i] .cnt){
if(S!= 1)f [S] ++;
戻る;
}
add(i、pos + 1、S);
add(i、pos + 1、S * arr [i] .fac [pos]);
戻る;
}
void del(int i、int pos、int S)
{
if(pos == arr [i] .cnt){
if(S!= 1)f [S]-;
戻る;
}
del(i、pos + 1、S);
del(i、pos + 1、S * arr [i] .fac [pos]);
戻る;
}
void read(void)
{
scanf( "%d%d"、&n、&k);
for(int i = 0; i <n; i ++){
scanf( "%d"、&t);
arr [i] .cnt = 0;
for(int j = 0; pri [j] * pri [j] <= t; j ++)
if(t%pri [j] == 0){
arr [i] .fac [arr [i] .cnt ++] = pri [j];
while(t%pri [j] == 0)
t / = pri [j];
}
if(t> 1)arr [i] .fac [arr [i] .cnt ++] = t;
if(i <2 * k)add(i、0,1);
}
n = 2 * k;
戻る;
}
int deg [100000]、F = -1、G = -1、H = -1;
int getdeg(int i、int pos、int S、int opt)
{
if(pos == arr [i] .cnt)
return opt * f [S];
戻り値getdeg(i、pos + 1、S、opt)+ getdeg(i、pos + 1、S * arr [i] .fac [pos]、-opt);
}
inline bool common(int a、int b)
{
int i = 0、j = 0;
while(i <arr [a] .cnt && j <arr [b] .cnt){
if(arr [a] .fac [i] == arr [b] .fac [j])
return 1;
if(arr [a] .fac [i]> arr [b] .fac [j])
j ++;
他のi ++;
}
0を返します。
}
void getFGH(int i)
{
F = i;
for(int j = 0; j <n; j ++)
if(!common(i、j)){
if(G ==-1)G = j;
else if(H ==-1)H = j;
}
return;
}
int getdeg(int i、int pos、int S、int opt)
{
if(pos == arr [i] .cnt)
return opt * f [S];
戻り値getdeg(i、pos + 1、S、opt)+ getdeg(i、pos + 1、S * arr [i] .fac [pos]、-opt);
}
inline bool common(int a、int b)
{
int i = 0、j = 0;
while(i <arr [a] .cnt && j <arr [b] .cnt){
if(arr [a] .fac [i] == arr [b] .fac [j])
return 1;
if(arr [a] .fac [i]> arr [b] .fac [j])
j ++;
他のi ++;
}
0を返します。
}
void getFGH(int i)
{
F = i;
for(int j = 0; j <n; j ++)
if(!common(i、j)){
if(G ==-1)G = j;
else if(H ==-1)H = j;
}
return;
}
void solve1(void)
{
for(int i = 0; i <n; i ++)
del(i、0,1);
int cnt = 0;
for(int i = 0; i <n && cnt <k; i ++)
if(getdeg(i、0,1、-1)== cnt){
cnt ++;
printf( "%d"、i + 1);
add(i、0,1);
}
return;
}
int check(int m)
{
int m0 = m + 1;
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H)
add(i、0,1);
それ以外の場合m0--;
int x = 0;
for(int i = 0; i <= m; i ++){
if(i == F || i == G || i == H)
続行;
deg [i] = m0-getdeg(i、0,1、-1);
if(deg [i]> 0)
x ++;
}
xを返します。
{
for(int i = 0; i <n; i ++)
del(i、0,1);
int cnt = 0;
for(int i = 0; i <n && cnt <k; i ++)
if(getdeg(i、0,1、-1)== cnt){
cnt ++;
printf( "%d"、i + 1);
add(i、0,1);
}
return;
}
int check(int m)
{
int m0 = m + 1;
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H)
add(i、0,1);
それ以外の場合m0--;
int x = 0;
for(int i = 0; i <= m; i ++){
if(i == F || i == G || i == H)
続行;
deg [i] = m0-getdeg(i、0,1、-1);
if(deg [i]> 0)
x ++;
}
xを返します。
void solve2(void)
{
for(int i = 0; i <n; i ++)
if(i!= F && i!= G && i!= H)
del(i、0,1);
int l = k-4、r = n-2、m;
while(l <r){
m =(l + r + 1)>> 1;
if(check(m)> = k-3)
r = m-1;
それ以外の場合、l = m;
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H)
del(i、0,1);
}
m = l + 1;
int p = check(m);
if(p> = k){
for(int i = 0; i <m && p> k; i ++)
if(i!= F && i!= G && i!= H && deg [i] == 1 &&!common(i、m)){
p--; deg [i] =-1;
}
}
else {
for(int i = 0; i <m && p> k-2;
p--; deg [i] =-1;
}
printf( "%d%d"、F + 1、G + 1);
if(p == k-3)
printf( "%d"、H + 1);
}
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H && deg [i]> 0)
printf( "%d"、i + 1);
戻る;
}
{
for(int i = 0; i <n; i ++)
if(i!= F && i!= G && i!= H)
del(i、0,1);
int l = k-4、r = n-2、m;
while(l <r){
m =(l + r + 1)>> 1;
if(check(m)> = k-3)
r = m-1;
それ以外の場合、l = m;
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H)
del(i、0,1);
}
m = l + 1;
int p = check(m);
if(p> = k){
for(int i = 0; i <m && p> k; i ++)
if(i!= F && i!= G && i!= H && deg [i] == 1 &&!common(i、m)){
p--; deg [i] =-1;
}
}
else {
for(int i = 0; i <m && p> k-2;
p--; deg [i] =-1;
}
printf( "%d%d"、F + 1、G + 1);
if(p == k-3)
printf( "%d"、H + 1);
}
for(int i = 0; i <= m; i ++)
if(i!= F && i!= G && i!= H && deg [i]> 0)
printf( "%d"、i + 1);
戻る;
}
int main(void)
{
getprime();
読んだ();
int w = 0;
for(int i = 0; i <n; i ++){
deg [i] = getdeg(i、0,1、-1);
if(deg [i] <n)w ++;
if(F ==-1 && deg [i] <= n-2)
getFGH(i);
}
if(F ==-1){
solve1();
0を返します。
}
for(int i = 0; i <n; i ++)
del(i、0,1);
if(check(n-1)<k-3){
for(int i = 0; i <n && k> 0; i ++)
if(deg [i] == 0){
printf( "%d"、i + 1 );
k--;
}
}
else solve2();
0を返します。
}
`` `
{
getprime();
読んだ();
int w = 0;
for(int i = 0; i <n; i ++){
deg [i] = getdeg(i、0,1、-1);
if(deg [i] <n)w ++;
if(F ==-1 && deg [i] <= n-2)
getFGH(i);
}
if(F ==-1){
solve1();
0を返します。
}
for(int i = 0; i <n; i ++)
del(i、0,1);
if(check(n-1)<k-3){
for(int i = 0; i <n && k> 0; i ++)
if(deg [i] == 0){
printf( "%d"、i + 1 );
k--;
}
}
else solve2();
0を返します。
}
`` `