[Arc080F]Prime Flip
[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的更多相关文章
- 【arc080F】Prime Flip
Portal --> arc080_f Solution 这题的话..差分套路题(算吗?反正就是想到差分就很好想了qwq) (但是问题就是我不会这种套路啊qwq题解原话是:&quo ...
- 【ARC080F】Prime Flip 差分+二分图匹配
Description 有无穷个硬币,初始有n个正面向上,其余均正面向下. 你每次可以选择一个奇质数p,并将连续p个硬币都翻转. 问最小操作次数使得所有硬币均正面向下. Input 第一行 ...
- Prime Flip AtCoder - 2689
发现我们每次区间取反,相邻位置的正反关系只有两个位置发生改变 我们定义bi为ai和ai-1的正反关系,即ai=ai-1时bi=0,否则bi=1,每次取反l~r,b[l]和b[r+1]会发生改变 容易发 ...
- AT2689 [ARC080D] Prime Flip
简要题解如下: 区间修改问题,使用差分转化为单点问题. 问题变成,一开始有 \(2n\) 个点为 \(1\),每次操作可以选择 \(r - l\) 为奇质数的两个点 \(l, r\) 使其 ^ \(1 ...
- 【Atcoder】ARC 080 F - Prime Flip
[算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...
- AT2689 Prime Flip
传送门 这个题是真的巧妙 首先一个很巧妙的思路,差分 考虑假如\(a_i!=a_{i-1}\),则\(b_i=1\),否则\(b_i=0\) 这样一来,一个区间的翻转就变成了对于两个数的取反了 然后我 ...
- [atARC080F]Prime Flip
构造一个数组$b_{i}$(初始为0),对于操作$[l_{i},r_{i}]$,令$b_{l_{i}}$和$b_{r_{i}+1}$值异或1,表示$i$和$i-1$的差值发生改变,最终即要求若干个$b ...
- AtCoder刷题记录
构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...
- Codeforces & Atcoder神仙题做题记录
鉴于Codeforces和atcoder上有很多神题,即使发呆了一整节数学课也是肝不出来,所以就记录一下. AGC033B LRUD Game 只要横坐标或者纵坐标超出范围就可以,所以我们只用看其中一 ...
随机推荐
- 20151024_001_C#基础知识(静态与非静态的区别,值类型和引用类型,堆和栈的区别,字符串的不可变性,命名空间)
1:我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出来类这个概念. 类就是个模子,确定了对象应该具有的属性和方法. 对象是根据类创建出来的. 2:类:语法 [public] class ...
- import学习
一.import as import socket, os, regex模块导入时可以使用 as 关键字来改变模块的引用对象名字: import os as system //当多个引入时 ...
- java和C和C++关系
java和C以及C++ 直接关联,java继承了C的语法,java的对象模型是从C++改编而来的.java和C以及C++关系之所以重要,下面几个就是原因: ①如果一个程序员熟悉C以及C++语法,那么他 ...
- python之计算器
开发一个简单的python计算器 1.实现加减乘除及拓号优先级解析 2.用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...
- 【Python学习】Jupyter解决单个变量输出问题
使用Jupyter的时候有时候发现,我明明写了好几个变量打印,但是它只显示最后一个.Out只有一个. 但是使用下面的语句.就可以实现多个输出. from IPython.core.interactiv ...
- Win10默认图片查看器更改
Win10自带的图片查看器不是很习惯,其背景乌漆嘛黑,宽扁的额头让人想起了黑边火腿肠手机,无法直视.怀念Win7和Win8.1的图片查看器,一个鼠标滚轮缩放自如的酸爽感觉.但却遗憾地发现,并不能直观地 ...
- iOS一个项目开始创建, 部署到git服务器
在做iOS开发时, 最开始可能你的经理部署项目, 所以你不会插手, 只是直接从git上clone下来然后就开始撸码, 如果有一天你做经理了, 你怎么去部署一个项目呢, 下面我来过一遍流程 1. 首先需 ...
- (转)关于bootstrap, boosting, bagging,Rand forest
转自:https://blog.csdn.net/jlei_apple/article/details/8168856 这两天在看关于boosting算法时,看到一篇不错的文章讲bootstrap, ...
- Content to Node: Self-Translation Network Embedding
paper:https://dl.acm.org/citation.cfm?id=3219988 data & code:http://dm.nankai.edu.cn/code/STNE.r ...
- Leetcode 之Binary Tree Preorder Traversal(42)
树的先序遍历.定义一个栈,先压入中间结点并访问,然后依次压入右.左结点并访问. vector<int> preorderTraversal(TreeNode *root) { vector ...