「LibreOJ β Round #4」子集

https://loj.ac/problem/526

题目描述

qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两个元素 i,j 均满足条件 gcd(ai,aj)×gcd(ai+1,aj+1)≠1,其中gcd(i,j)表示最大公约数,且这个子集的元素个数是所有满足上述条件的子集中最多的。输出这个子集的元素个数。

输入格式

输入的第一行包含一个正整数nnn。 随后nnn行,每行一个正整数aia_ia?i??。

输出格式

输出一个整数代表符合条件的元素最多的子集的元素个数。

样例

样例输入1

4
4
6
1
9

样例输出1

3

样例解释

选择的子集为{1,2,4}\{1,2,4\}{1,2,4}。

样例输入2

41
71
3
5
50
75
2
19
47
88
95
92
110
111
117
58
124
130
57
129
168
161
29
39
206
79
10
142
107
209
210
222
221
223
242
104
264
265
202
279
314
315

样例输出2

22

奇数和奇数、偶数和偶数一定可以选在一起所以对于不满足条件的奇数和偶数,连边求最大点独立集即点数-匹配数

#include<cstdio>
#include<iostream>
#define N 501
using namespace std;
typedef long long LL;
int n;
LL a[N],b[N];
bool g[N][N],vis[N];
int match[N];
void read(int &x)
{
    x=0; int f=1; char c=getchar();
    while(!isdigit(c)) { if(c==‘-‘) f=-1;  c=getchar(); }
    while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); }
    x*=f;
}
void read(LL &x)
{
    x=0; int f=1; char c=getchar();
    while(!isdigit(c)) { if(c==‘-‘) f=-1;  c=getchar(); }
    while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); }
    x*=f;
}
inline LL gcd(LL p,LL q) { return !q ? p : gcd(q,p%q); }
bool go(int now)
{
    for(int i=1;i<=b[0];i++)
    {
        if(vis[i] || !g[now][i]) continue;
        vis[i]=true;
        if(!match[i] || go(match[i]))
        {
            match[i]=now;
            return true;
        }
    }
    return false;
}
int main()
{
    read(n);
    LL x;
    for(int i=1;i<=n;i++)
    {
        read(x);
        (x&1 ? a[++a[0]] : b[++b[0]])=x;
    }
    for(int i=1;i<=a[0];i++)
        for(int j=1;j<=b[0];j++)
            if(gcd(a[i],b[j])==1 && gcd(a[i]+1,b[j]+1)==1) g[i][j]=true;
    int sum=0;
    for(int i=1;i<=a[0];i++)
    {
        fill(vis+1,vis+b[0]+1,0);
        if(go(i)) sum++;
    }
    printf("%d",n-sum);
} 


时间: 2024-08-10 17:17:59

「LibreOJ β Round #4」子集的相关文章

LibreOJ #526. 「LibreOJ β Round #4」子集

二次联通门 : LibreOJ #526. 「LibreOJ β Round #4」子集 /* LibreOJ #526. 「LibreOJ β Round #4」子集 考虑一下,若两个数奇偶性相同 若同为奇数, 那加1后就是偶数, gcd的乘积就一定不是1 偶数相同 那么我们把原数中的偶数分为一个集合,奇数分为一个集合 把互相之间不符合要求的连边 那么问题就转化为了二分图求最大独立集 */ #include <cstdio> #include <iostream> #includ

LOJ 「LibreOJ β Round #4」子集

一道脑洞题,我们发现不能在一起的点对还是比较少的. 我们考虑奇偶性,发现同奇偶性时一定可以,那么我们统计不可以的对,答案就是n-二分图的最大匹配. #include<bits/stdc++.h> #define N 507 #define int long long using namespace std; int x,a[N],b[N],usd[N],c[N],d[N][N],n,ta,tb,tot; int gcd(int x,int y){ return y?gcd(y,x%y):x;

loj526「LibreOJ β Round #4」子集

分析 求满足条件的最大团 我们可以考虑建出补图 发现对于奇数之间和偶数之间 由于一定满足所以补图上一定可以将奇数一组偶数一组建成一个二分图 求二分图最大独立集即可 代码 #include<bits/stdc++.h> using namespace std; #define int long long int n,m,d[1010],g[1010][1010],a[1010],b[1010],c1,c2,ans,T,used[1010],wh[1010]; inline bool work(i

LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例

二次联通门 : LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例 /* LibreOJ #515. 「LibreOJ β Round #2」贪心只能过样例 很显然 贪心方程哦不 dp方程为 f[i][j]=f[i-1][j-k*k] 但是这样的话复杂度就是O(N ^ 5) 那么就用bitset优化一下 就ok了 */ #include <iostream> #include <cstdio> #include <bitset> void

LibreOJ「LibreOJ β Round #4」 游戏

二次联通门 : LibreOJ「LibreOJ β Round #4」 游戏 /* LibreOJ「LibreOJ β Round #4」 游戏 找找规律就会发现.. 当有X的时候,答案跟X个数的奇偶有关 否则就求一下逆序对就好了.. 由于SB的错误..WA了3发才过 然后就签完到走人了 */ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #defi

LibreOJ #514. 「LibreOJ β Round #2」模拟只会猜题意

二次联通门 : LibreOJ #514. 「LibreOJ β Round #2」模拟只会猜题意 /* LibreOJ #514. 「LibreOJ β Round #2」模拟只会猜题意 本想打个暴力找找规律 结果交上去就A了... 读入所有数 处理出前缀和 然后枚举区间长度 处理处1~n的答案 后O(1)查询即可 复杂度O(n^2 + m) */ #include <iostream> #include <cstring> #include <cstdio> voi

LibreOJ #525. 「LibreOJ β Round #4」多项式

二次联通门 : LibreOJ #525. 「LibreOJ β Round #4」多项式 官方题解 : /* LibreOJ #525. 「LibreOJ β Round #4」多项式 由于会有多种解 所以只需要找出一组特殊解即可 */ #include <cstdio> #include <iostream> void read (int &now) { register char c = getchar (); for (now = 0; !isdigit (c);

LibreOJ #528. 「LibreOJ β Round #4」求和

二次联通门 : LibreOJ #528. 「LibreOJ β Round #4」求和 /* LibreOJ #528. 「LibreOJ β Round #4」求和 题目要求的是有多少对数满足他们的最大公约数的质因子不超过一个 f (x) 表示有多少对数满足最大公约数中含有x^2这个因子 那么f (x) = N / x ^ 2 * M * (x ^ 2) 答案即为所有数字减去不符合要求的数字个数 但是我们发现,可能某对数字的最大公约数含有多个质数平方因子 那么在处理的时候就会重复筛去 这时我

LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力

二次联通门 : LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 /* LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 叫做计算几何 实则毒瘤数据结构 看到xor后 考虑Trie树 Trie树的每一个节点保存的是以当前子树中每个二进制位的个数 给Trie打一个全局xor标记,如果标记这一位是1,就交换它的两个儿子 另外维护一个前缀和 前缀和存的是没sort过的值的和 Trie维护的是sort之后的值 1操作直接在前缀和后加就好