[Arc080F]Prime Flip

Description

你有无限多的“给给全”,编号为1,2,3,...。开始时,第x1,x2,...,xN个“给给全”是躺着的,其它的“给给全”是趴着的 你可以进行一些操作,每个操作大概是这样的: 选择一个不小于3的质数p,然后将连续的p个“给给全”翻过来 你希望让所有“给给全”趴下。请计算完成这一任务所需的最少操作次数

Input

第一行一个正整数N

第二行N个正整数,第i个数表示xi

Output

一个整数表示最小操作步数

Sample Input

Sample #1

2

4 5

Sample #2

9

1 2 3 4 5 6 7 8 9

Sample #3

2

1 10000000

Sample Output

Sample #1

2

Sample #2

3

Sample #3

4

HINT

样例一可以先选择5,并翻转1,2,3,4,5。然后选择3,并翻转1,2,3

\(1\leq N \leq 100\)

\(1\leq x_1\leq x_2\leq ... \leq x_N\leq 10^7\)

试题分析

首先遇到这种翻转的问题,进行差分,因为这样可以把一段区间的操作看成简单的翻转\(i\)和\(i+p\)个状态的操作。

那么我们希望用最小的步骤使其最优,要怎么办呢?

首先列一个表出来,可以得出结论:1格需要翻转3遍,奇质数需要翻转1遍,偶数需要翻转2遍,奇合数需要翻转3遍。

其中结论1为手推,结论2为题目标准操作,结论3是哥德巴赫猜想,结论4是奇合数可以通过减去一个奇质数得到偶数长度。

于是我们就希望尽量先选翻转1遍的奇质数情况,一定是一奇一偶配对,使其配对数最大。

那么到这里做法就很显然了,直接二分图匹配,然后剩下的单算,注意最后剩1格的情况。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm> using namespace std;
#define LL long long inline int read(){
int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int INF = 2147483600;
const int MAXN = 10000010; bool vis[MAXN+1];int pri[MAXN+1],cnt;
int flo[MAXN+1]; int N;
int sta[2][20010],top[2];
int Next[20010],Node[20010],Root[20010]; inline void init(){
vis[1]=true;
for(int i=2;i<=MAXN;i++){
if(!vis[i]) pri[++cnt]=i;
for(int j=1;j<=cnt&&pri[j]*i*1LL<=MAXN;j++){
vis[i*pri[j]]=true; if(i%pri[j]==0) break;
}
} return ;
}
int fa[200010];
inline bool dfs(int k){
for(int x=Root[k];x;x=Next[x]){
int v=Node[x];
if(!vis[v]){
vis[v]=true;
if(fa[v]==-1||dfs(fa[v])){
fa[v]=k; return true;
}
}
} return false;
}
inline void insert(int u,int v){
Node[++cnt]=v; Next[cnt]=Root[u]; Root[u]=cnt; return ;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
for(int i=0;i<=MAXN;i++) flo[i]=1; N=read();
for(int i=1;i<=N;i++){
int x=read(); flo[x]=0;
} init(); for(int i=MAXN;i>=1;i--) {
flo[i]=flo[i]-flo[i-1];
if(flo[i]){
sta[i&1][++top[i&1]]=i;
}
}
for(int i=1;i<=top[0];i++){
for(int j=1;j<=top[1];j++){
if(!vis[abs(sta[0][i]-sta[1][j])]){
insert(i,j+top[0]);
//insert(j+top[0],i);
}
}
} int ans=0;
memset(fa,-1,sizeof(fa));
for(int i=1;i<=top[0];i++){
memset(vis,false,sizeof(vis));
ans+=dfs(i);
}
printf("%d\n",ans+(top[0]-ans)/2*2+(top[1]-ans)/2*2+((top[0]-ans)&1)*3LL);
return 0;
}

[Arc080F]Prime Flip的更多相关文章

  1. 【arc080F】Prime Flip

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

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

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

  3. Prime Flip AtCoder - 2689

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

  4. AT2689 [ARC080D] Prime Flip

    简要题解如下: 区间修改问题,使用差分转化为单点问题. 问题变成,一开始有 \(2n\) 个点为 \(1\),每次操作可以选择 \(r - l\) 为奇质数的两个点 \(l, r\) 使其 ^ \(1 ...

  5. 【Atcoder】ARC 080 F - Prime Flip

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

  6. AT2689 Prime Flip

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

  7. [atARC080F]Prime Flip

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

  8. AtCoder刷题记录

    构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...

  9. Codeforces & Atcoder神仙题做题记录

    鉴于Codeforces和atcoder上有很多神题,即使发呆了一整节数学课也是肝不出来,所以就记录一下. AGC033B LRUD Game 只要横坐标或者纵坐标超出范围就可以,所以我们只用看其中一 ...

随机推荐

  1. CSS 竖线颜色渐变

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"& ...

  2. Python 语言使用中遇到的问题汇总

    1.python中的传值和传引用 和其他语言不一样,传递参数的时候,python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方式.实际上,这种方式相当于传值和传 ...

  3. mssql手工注入1

    强制字符转成数字, 所以报错, 能获得数据 查版本号: http: -- 查数据库版本: http: -- 查当前数据库用户(如果看到dbo 那么多半当前数据库的用户是dba权限): http: -- ...

  4. ARM中断向量表与响应流程【转】

    转自:http://blog.csdn.net/honour2sword/article/details/40213417 一首先中断向量表定义在哪里?如何加载? 二 中断向量表与中断服务程序 三处理 ...

  5. cacti (不可以利用yum安装cacti的配置)

    我们如果用yum不可以安装cacti,我们则可以利用tar包来安装!!! //cacti的配置准备 [root@localhost ~]# yum install -y epel-release [r ...

  6. linux命令(20):rm命令

    1. 强行删除文件,系统不再确认:rm –f test.log 2. 删除任何.log文件:rm *.log 3. 将test子目录及子目录中所有档案删除:rm –r  test 4. 将 test子 ...

  7. [转载] Python itertools模块详解

    原文在这里,写的很详细,感谢原作者,以下摘录要点. itertools用于高效循环的迭代函数集合. 无限迭代器 迭代器 参数 结果 例子 count() start, [step] start, st ...

  8. 【转载】PDB命令行调试Python代码

    转载自这里. (博主按:PDB调试python代码和用GDB调试c++代码很类似) 你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多.然而, ...

  9. MySQL中的内连接、外连接、交叉连接

    内连接(INNER JOIN):   分为三种 等值连接.自然连接.不等连接        外连接(OUTER JOIN):   左外连接(LEFT OUTER JOIN或LEFT JOIN)   右 ...

  10. node-java模块

    node-java模块 node-java使得开发人员,可以调用java优秀的jar包资源.有些方法逻辑,可能node不容易实现,但是java就可以很方便去做.这个时候,就可以使用node-java这 ...