AT2689 [ARC080D] Prime Flip
简要题解如下:
区间修改问题,使用差分转化为单点问题。
问题变成,一开始有 \(2n\) 个点为 \(1\),每次操作可以选择 \(r - l\) 为奇质数的两个点 \(l, r\) 使其
^\(1\)。根据哥德巴赫猜想可以发现,若 \(r - l\) 为奇质数显然一次即可,若 \(r - l\) 为偶数则需两次,若 \(r - l\) 为奇数则需三次。
近一步可以发现,若想消去两个点 \(l, r\) 则涉及其他点是可以通过调整使得直接消去两个点的。
更近一步可以发现,将所有点按照奇偶分类,显然若消去奇偶性相同的两个数只能 \(2\) 次,那么首先将差是奇质数的点一起消去肯定是最优的。
因为差是奇质数的点必然一个为偶数一个为奇数构成二分图,于是可以使用匈牙利或网络流解决二分图最大匹配问题。
剩下的肯定要同集合内部按照 \(2\) 次消去,最后若还剩一个元素才使用 \(3\) 次的方法。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define Next(i, u) for (int i = cur[u]; i; i = e[i].next)
const int N = 2e4 + 5;
const int M = 1e7 + 5;
struct edge { int v, next, w;} e[N << 1];
int n, s, t, F, ans, cnt, tot = 1, ton[2], a[N], h[N], d[M];
namespace PR {
bool iprime[M]; int tot, prime[M];
void sieve(int L) {
iprime[1] = 1;
rep(i, 2, L) {
if(!iprime[i]) prime[++tot] = i;
for (int j = 1; j <= tot && i * prime[j] <= L; ++j) {
iprime[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
}
namespace FL {
bool book[N]; int dep[N], cur[N];
bool bfs(int s, int t) {
rep(i, s, t) cur[i] = h[i], dep[i] = -t;
queue <int> Q;
dep[s] = 1, Q.push(s);
while (!Q.empty()) {
int u = Q.front(); Q.pop();
Next(i, u) {
int v = e[i].v; if(!e[i].w || dep[v] > 0) continue;
dep[v] = dep[u] + 1, Q.push(v);
}
}
return dep[t] > 0;
}
int dfs(int u, int lim) {
if(u == t) return lim;
int flow = 0, rflow = 0; book[u] = true;
Next(i, u) {
int v = e[i].v; cur[u] = i;
if(!book[v] && dep[v] == dep[u] + 1 && e[i].w && (rflow = dfs(v, min(e[i].w, lim)))) {
flow += rflow, lim -= rflow, e[i].w -= rflow, e[i ^ 1].w += rflow;
if(!lim) break;
}
}
book[u] = false; return flow;
}
}
void add(int u, int v, int w) {
e[++tot].v = v, e[tot].w = w, e[tot].next = h[u], h[u] = tot;
e[++tot].v = u, e[tot].w = 0, e[tot].next = h[v], h[v] = tot;
}
int main () {
cin >> n;
rep(i, 1, n) cin >> a[i], d[a[i]] ^= 1, d[a[i] + 1] ^= 1;
PR :: sieve(M - 1);
s = cnt = 1;
rep(i, 1, M - 1) if(d[i]) a[++cnt] = i, ++ton[i & 1];
t = ++cnt;
rep(i, 2, cnt - 1) {
if(a[i] & 1) add(s, i, 1);
else add(i, t, 1);
}
rep(i, 2, cnt - 1) if(a[i] & 1) {
rep(j, 2, cnt - 1) if(!(a[j] & 1) && !(PR :: iprime[abs(a[j] - a[i])])) add(i, j, 1);
}
while (FL :: bfs(s, t)) ans += FL :: dfs(s, cnt);
if((ton[0] - ans) & 1) F = 1;
ans += 2 * ((ton[0] - ans) / 2 + (ton[1] - ans) / 2);
ans += F * 3;
printf("%d", ans);
return 0;
}
首先区间修改差分转单点是非常重要的,可以减少有效修改点数,方便于观察问题。
对于某个数能被质数 / 奇质数组成的问题,一定要敏锐地想到 哥德巴赫猜想
AT2689 [ARC080D] Prime Flip的更多相关文章
- [Arc080F]Prime Flip
[Arc080F]Prime Flip Description 你有无限多的"给给全",编号为1,2,3,....开始时,第x1,x2,...,xN个"给给全" ...
- AT2689 Prime Flip
传送门 这个题是真的巧妙 首先一个很巧妙的思路,差分 考虑假如\(a_i!=a_{i-1}\),则\(b_i=1\),否则\(b_i=0\) 这样一来,一个区间的翻转就变成了对于两个数的取反了 然后我 ...
- Prime Flip AtCoder - 2689
发现我们每次区间取反,相邻位置的正反关系只有两个位置发生改变 我们定义bi为ai和ai-1的正反关系,即ai=ai-1时bi=0,否则bi=1,每次取反l~r,b[l]和b[r+1]会发生改变 容易发 ...
- 【arc080F】Prime Flip
Portal --> arc080_f Solution 这题的话..差分套路题(算吗?反正就是想到差分就很好想了qwq) (但是问题就是我不会这种套路啊qwq题解原话是:&quo ...
- 【ARC080F】Prime Flip 差分+二分图匹配
Description 有无穷个硬币,初始有n个正面向上,其余均正面向下. 你每次可以选择一个奇质数p,并将连续p个硬币都翻转. 问最小操作次数使得所有硬币均正面向下. Input 第一行 ...
- 【Atcoder】ARC 080 F - Prime Flip
[算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...
- [atARC080F]Prime Flip
构造一个数组$b_{i}$(初始为0),对于操作$[l_{i},r_{i}]$,令$b_{l_{i}}$和$b_{r_{i}+1}$值异或1,表示$i$和$i-1$的差值发生改变,最终即要求若干个$b ...
- Java基础之写文件——从多个缓冲区写(GatheringWrite)
控制台程序,使用单个写操作将数据从多个缓冲区按顺序传输到文件,这称为集中写(GatheringWrite)操作.这个功能的优势是能够避免在将信息写入到文件中之前将信息复制到单个缓冲区中.从每个缓冲区写 ...
- Atcoder 乱做
最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...
随机推荐
- 前端项目 node8升级到node16,代码升级汇总
背景 公司的项目是vue项目,环境是node@8x版本的,最近我创建react hook的项目,发现至少需要node14才支持,打开官网才发现node都已经到16版本了.失策啊,失策.于是直接升级到最 ...
- [zbar]zbar条码扫描器解析示例
// // Created by leoxae on 2020/3/30. // #include "BarCodeRecogntion.h" string BarCode::Ba ...
- [opencv]drawContours 示例
vector<vector<Point>> contours; vector<Vec4i> hierarchy; findContours(img_canny,co ...
- VUE3 之 click 事件
1. 概述 老话说的好:努力帮别人解决难题,你的难题也就不难解决了. 言归正传,今天我们来聊聊 VUE3 的 click 事件的相关知识. 2. click 事件 2.1 实现数字递减 <bod ...
- Windows Server 2016 服务器安装IIS
1. 打开服务器管理器,点击[添加角色和功能选项] 2.进入[添加角色和功能向导]页面,点击"下一步" 3.安装类型选择[基于角色或基于功能的安装],点击"下一步&q ...
- C#读取注释的方法
友好的注释能提高代码的可读性,几乎所有的编程语言都支持注释. 在C#中,注释不是可执行代码的一部分,因此注释不会被编译到程序集中去,但是我们可以提取注释[右键项目]-[属性]-[生成]-[输出]-[X ...
- 使用sudo执行命令提示command not found
笔记: 使用源码部署nginx的时候,使用sudo nginx提示command not found,但是直接使用nginx会导致权限问题: 这种情况应该是环境变量导致的,使用 env |grep P ...
- 官网下载mysql的方法
mysql官网 http://www.mysql.com/ 方法一: (1)登陆官网 (2)把页面拉到最底部,点击Downloads(GA) 下边的MySQL Community Serv ...
- MySQL存储过程入门基础
创建存储过程无参语法: delimiter // create procedure 函数名() begin 业务逻辑 end // call 函数名() 通过函数名调用存储过程 创建存储过程有参与法: ...
- ubuntu的一些常用操作
查看当前正在运行的操作系统版本 $ cat /etc/issue 查看操作系统详细信息 $ sudo lsb_release -a 查看内核版本号 $ uname -r 卸载软件(不保留配置文件) $ ...