简要题解如下:

  1. 区间修改问题,使用差分转化为单点问题。

  2. 问题变成,一开始有 \(2n\) 个点为 \(1\),每次操作可以选择 \(r - l\) 为奇质数的两个点 \(l, r\) 使其 ^ \(1\)。

  3. 根据哥德巴赫猜想可以发现,若 \(r - l\) 为奇质数显然一次即可,若 \(r - l\) 为偶数则需两次,若 \(r - l\) 为奇数则需三次。

  4. 近一步可以发现,若想消去两个点 \(l, r\) 则涉及其他点是可以通过调整使得直接消去两个点的。

  5. 更近一步可以发现,将所有点按照奇偶分类,显然若消去奇偶性相同的两个数只能 \(2\) 次,那么首先将差是奇质数的点一起消去肯定是最优的。

  6. 因为差是奇质数的点必然一个为偶数一个为奇数构成二分图,于是可以使用匈牙利或网络流解决二分图最大匹配问题。

  7. 剩下的肯定要同集合内部按照 \(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的更多相关文章

  1. [Arc080F]Prime Flip

    [Arc080F]Prime Flip Description 你有无限多的"给给全",编号为1,2,3,....开始时,第x1,x2,...,xN个"给给全" ...

  2. AT2689 Prime Flip

    传送门 这个题是真的巧妙 首先一个很巧妙的思路,差分 考虑假如\(a_i!=a_{i-1}\),则\(b_i=1\),否则\(b_i=0\) 这样一来,一个区间的翻转就变成了对于两个数的取反了 然后我 ...

  3. Prime Flip AtCoder - 2689

    发现我们每次区间取反,相邻位置的正反关系只有两个位置发生改变 我们定义bi为ai和ai-1的正反关系,即ai=ai-1时bi=0,否则bi=1,每次取反l~r,b[l]和b[r+1]会发生改变 容易发 ...

  4. 【arc080F】Prime Flip

    Portal --> arc080_f Solution ​  这题的话..差分套路题(算吗?反正就是想到差分就很好想了qwq) ​​  (但是问题就是我不会这种套路啊qwq题解原话是:&quo ...

  5. 【ARC080F】Prime Flip 差分+二分图匹配

    Description ​ 有无穷个硬币,初始有n个正面向上,其余均正面向下.  你每次可以选择一个奇质数p,并将连续p个硬币都翻转.  问最小操作次数使得所有硬币均正面向下. Input ​ 第一行 ...

  6. 【Atcoder】ARC 080 F - Prime Flip

    [算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...

  7. [atARC080F]Prime Flip

    构造一个数组$b_{i}$(初始为0),对于操作$[l_{i},r_{i}]$,令$b_{l_{i}}$和$b_{r_{i}+1}$值异或1,表示$i$和$i-1$的差值发生改变,最终即要求若干个$b ...

  8. Java基础之写文件——从多个缓冲区写(GatheringWrite)

    控制台程序,使用单个写操作将数据从多个缓冲区按顺序传输到文件,这称为集中写(GatheringWrite)操作.这个功能的优势是能够避免在将信息写入到文件中之前将信息复制到单个缓冲区中.从每个缓冲区写 ...

  9. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

随机推荐

  1. Codeforces 567D:One-Dimensional Battle Ships(二分)

    time limit per test : 1 second memory limit per test : 256 megabytes input : standard input output : ...

  2. matplotlib 进阶之Tight Layout guide

    目录 简单的例子 Use with GridSpec Legend and Annotations Use with AxesGrid1 Colorbar 函数链接 matplotlib教程学习笔记 ...

  3. 从源码看全局异常处理器@ExceptionHandler&@ExceptionHandler的生效原理

    1.开头在前 日常开发中,几乎我们的项目都会用到异常处理器,我们通常会定制属于自己的异常处理器,来处理项目中大大小小.各种各样的异常.配置异常处理器目前最常用的方式应该是使用@ControllerAd ...

  4. Salesforce LWC学习(三十八) lwc下如何更新超过1万的数据

    背景: 今天项目组小伙伴问了一个问题,如果更新数据超过1万条的情况下,有什么好的方式来实现呢?我们都知道一个transaction只能做10000条DML数据操作,那客户的操作的数据就是超过10000 ...

  5. Deepin20系统安装Nvidia驱动

    Deepin20系统安装Nvidia驱动 系统设备配置信息如下: 电脑型号:华硕天选air[ASUS-FX516P] 显卡型号:RTX 3070 移动版独显 处理器型号: 11th Gen Intel ...

  6. Oracle中的基本数据类型

    一.Oracle 基本数据类型 1.字符数据类型 CHAR:存储固定长度的字符串,如果没有指定长度,默认为1个字节,如果数据长度没有达到指定的长度,则通过填充空格的方式来使其达到定义的长度(CHAR类 ...

  7. ActiveMQ基础教程(三):C#连接使用ActiveMQ消息队列

    接上一篇:ActiveMQ基础教程(二):安装与配置(单机与集群) 安装部署好集群环境:192.168.209.133:61616,192.168.209.134:61616,192.168.209. ...

  8. linux 部署.net core 环境

    Linux版本Ubuntu 16.04 .net core 下载地址:https://dotnet.microsoft.com/download/dotnet-core/2.1 虽然现在现在.net ...

  9. exit hook

    之前经常改 malloc_hook , realloc_hook,free_hook 为 one_gadget 来 get shell ,最近看到一种利用是改 exit hook(winmt师傅告诉我 ...

  10. visual studio code 修改工具栏风格

    用windows版vscode的同学们是否发现它的工具栏是白色的跟整个界面看起来不太搭调,如下图: 其实要改变标题栏颜色也很简单,点击:文件> 首选项>设置 将 "window. ...