[LOJ#526]「LibreOJ β Round #4」子集

试题描述

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

输入

输入的第一行包含一个正整数n。 随后n行,每行一个正整数ai。

输出

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

输入示例


输出示例


数据规模及约定

1≤n≤500

1≤ai≤1018

题解

直接建图(若 (i, j) 符合 gcd(ai,aj)×gcd(ai+1,aj+1)≠1 则在 i 和 j 之间添边),然后跑最大团。然而我并不会强剪枝。

于是考虑建补图,然后找最大独立集。对于补图,i, j 之间存在边当且仅当 gcd(ai,aj)=1 且 gcd(ai+1,aj+1)=1,若 ai 和 aj 同奇偶,则 ai 和 aj 都是偶数或 ai+1 和 aj+1 都是偶数,不可能存在边 (i, j),所以这个补图就是一个二分图。根据“最大独立集 = n - 最小点覆盖 = n - 最大匹配”可求得答案。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
using namespace std;
#define LL long long LL read() {
LL x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 510
#define maxm 500010
#define oo 2147483647 struct Edge {
int from, to, flow;
Edge() {}
Edge(int _1, int _2, int _3): from(_1), to(_2), flow(_3) {}
};
struct Dinic {
int n, m, s, t, head[maxn], nxt[maxm];
Edge es[maxm];
int vis[maxn], Q[maxn], hd, tl;
int cur[maxn]; void init() {
m = 0; memset(head, -1, sizeof(head));
return ;
}
void setn(int _) { n = _; return ; } void AddEdge(int a, int b, int c) {
es[m] = Edge(a, b, c); nxt[m] = head[a]; head[a] = m++;
es[m] = Edge(b, a, 0); nxt[m] = head[b]; head[b] = m++;
return ;
} bool BFS() {
memset(vis, 0, sizeof(vis));
vis[s] = 1;
hd = tl = 0; Q[++tl] = s;
while(hd < tl) {
int u = Q[++hd];
for(int i = head[u]; i != -1; i = nxt[i]) {
Edge& e = es[i];
if(e.flow && !vis[e.to]) {
vis[e.to] = vis[u] + 1;
Q[++tl] = e.to;
}
}
}
return vis[t] > 0;
}
int DFS(int u, int a) {
if(u == t || !a) return a;
int flow = 0, f;
for(int& i = cur[u]; i != -1; i = nxt[i]) {
Edge& e = es[i];
if(vis[e.to] == vis[u] + 1 && (f = DFS(e.to, min(a, e.flow)))) {
flow += f; a -= f;
e.flow -= f; es[i^1].flow += f;
if(!a) return flow;
}
}
return flow;
}
int MaxFlow(int _s, int _t) {
s = _s; t = _t;
int flow = 0;
while(BFS()) {
for(int i = 1; i <= n; i++) cur[i] = head[i];
flow += DFS(s, oo);
}
return flow;
}
} sol; LL A[maxn];
LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } int main() {
int n = read();
for(int i = 1; i <= n; i++) A[i] = read(); sol.init();
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if(gcd(A[i], A[j]) == 1 && gcd(A[i] + 1, A[j] + 1) == 1) {
int a = i, b = j;
if(A[a] & 1) swap(a, b);
sol.AddEdge(a, b, 1); // even -> odd
}
int s = n + 1, t = n + 2;
for(int i = 1; i <= n; i++)
if(A[i] & 1) sol.AddEdge(i, t, 1);
else sol.AddEdge(s, i, 1); sol.setn(n + 2);
printf("%d\n", n - sol.MaxFlow(s, t)); return 0;
}

[LOJ#526]「LibreOJ β Round #4」子集的更多相关文章

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

    二次联通门 : LibreOJ #526. 「LibreOJ β Round #4」子集 /* LibreOJ #526. 「LibreOJ β Round #4」子集 考虑一下,若两个数奇偶性相同 ...

  2. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  3. [LOJ#530]「LibreOJ β Round #5」最小倍数

    [LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...

  4. [LOJ#516]「LibreOJ β Round #2」DP 一般看规律

    [LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...

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

    [LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...

  6. [LOJ#525]「LibreOJ β Round #4」多项式

    [LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...

  7. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...

  8. loj #547. 「LibreOJ β Round #7」匹配字符串

    #547. 「LibreOJ β Round #7」匹配字符串   题目描述 对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的任意一个长度为 ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

随机推荐

  1. HDU 5092 Seam Carving (dp)

    题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条. 数字三角形打印路径... 一般打印路径有两种选择,一是转移的时候加以记录,二是通过检查dp值回溯. ...

  2. [学习笔记] C++ 历年试题解析(二)--程序题

    发现程序题也挺有价值的. 顺便记录下来几道. 1.题目 #include <iostream> #include <cstring> using namespace ① std ...

  3. Context 使用不当造成内存泄露

    问题: Activity中的context被传递给了一个生命周期长过activity的对象(通常为静态单实例变量),导致activity不能正常被销毁. 示例:Activity 调用 ChatMgr ...

  4. Acronis.Disk.Director磁盘分区管理

    Acronis.Disk.Director分为for 专业版和服务器版的,我在生产环境中调整Windows2003跳板机使用的是Acronis.Disk.Director Server 10.0.20 ...

  5. Bootstrap历练实例:动画的进度条

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. Maven各种常用架包配置文件,保存一份

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  7. 【转】matlab练习程序(奇异值分解压缩图像)

    介绍一下奇异值分解来压缩图像.今年的上半年中的一篇博客贴了一篇用奇异值分解处理pca问题的程序,当时用的是图像序列,是把图像序列中的不同部分分离开来.这里是用的不是图像序列了,只是单单的一幅图像,所以 ...

  8. C++ 学习笔记 开篇

    从大一开始学习C语言,大学期间做了许多嵌入式的开发项目,毕业后从事嵌入式开发工作主要的开发语言也是C语言.虽然期间断断续续的学习过C++,做过QT.C#上位机但也只是在其他语言的外壳下使用C在开发,始 ...

  9. Docker 容器的网络连接 & 容器互联

    1. Docker 容器网络基础架构 Docker0 ifconfig查看到的 docker0 是linux的虚拟网桥(OSI数据链路层) docker0 地址划分: 172.17.42.1 255. ...

  10. Python分布式爬虫开发搜索引擎 Scrapy实战视频教程

    点击了解更多Python课程>>> Python分布式爬虫开发搜索引擎 Scrapy实战视频教程 课程目录 |--第01集 教程推介 98.23MB |--第02集 windows下 ...