[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 只要横坐标或者纵坐标超出范围就可以,所以我们只用看其中一 ...
随机推荐
- bzoj 3197 DP
这道题我们可以看成给定两个黑白树,可以修改其中一棵树的颜色,问最少修改多少颜色可以使两棵树同构. 首先我们知道在树的同构中树上最长链中点(如果是偶数的话就是中间两个点)是不变的,我们把这个点叫做树的重 ...
- 函数getopt()及其参数optind -- (转)
getopt被用来解析命令行选项参数 #include <unistd.h> extern char *optarg; //选项的参数指针 extern int ...
- hdu 1200 To and Fro(简单模拟或DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1200 To and Fro Time Limit: 2000/1000 MS (Java/Others ...
- vue路由-基础
安装 1.直接下载 / CDN https://unpkg.com/vue-router/dist/vue-router.js 在 Vue 后面加载 vue-router,它会自动安装的: <s ...
- TCP之listen&backlog
1. listen函数: #include <sys/socket.h> int listen(int sockfd, int backlog); ret-成功返回0 失败返回- list ...
- Linux-进程间通信(六): 记录锁
1. 记录锁:记录锁的功能是,当一个进程正在读或者修改文件的某个部分的时候,它可以阻止其他进程修改同一文件区: 2. fcntl记录锁: #include <fcntl.h> int fc ...
- 自动化测试===Macaca环境搭建和说明书
https://www.cnblogs.com/tim2016/p/6400326.html http://www.cnblogs.com/fnng/p/5873878.html https://ww ...
- pxc群集搭建
pxc群集搭建 1.环境 Percona-XtraDB 5.7.22-22-29.26-log percona-xtrabackup-24-2.4.12 192.168.99.210:3101(第一节 ...
- java web 资源文件读取
前提:假设web应用test(工程名) webapps下面有一资源文件test.html 规则:在获取资源时一般使用的是相对路径,以符号/开头,而 / 代表什么取决于这个地址给谁使用.服务器使用时,/ ...
- [ python ] 项目一:FTP程序
声明: 该项目参考学习地址: http://www.cnblogs.com/lianzhilei/p/5869205.html , 感谢博主分享,如有侵权,立即删除. 作业:开发一个支持多用户在线的F ...