发现我们每次区间取反,相邻位置的正反关系只有两个位置发生改变
我们定义bi为ai和ai-1的正反关系,即ai=ai-1时bi=0,否则bi=1,每次取反l~r,b[l]和b[r+1]会发生改变
容易发现b[i]=1的位置一定是偶数个,我们将他们取出来
因为每次取反一定会改变两个b[i],所以我们将这些位置两两配对消去
两个位置i,j,有三种配对
|i-j|是奇素数,可以直接消去,最少花费1次操作
|i-j|是偶数,可以由奇素数的和(哥德巴赫猜想?)或差得到,最少花费2次
|i-j|是奇非素数,由奇素数和偶数差得到,最少花费3次
将b[i]=1的i按奇偶性分为两个集合
不同集合之间的配对是第1、3种配对
同一集合间的配对是第2种
可以做第一种配对的i,j之间连边,找二分图最大匹配
剩下的两个集合内部两两第二种配对
如果还余1个,作第三种配对

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<cstdio>
  6. using namespace std;
  7. #define CLR(a,b) memset(a,b,sizeof(a))
  8. const int maxn = 1e7 + 10;
  9. int a[maxn];
  10. int b[maxn];
  11. int n;
  12.  
  13. int point[210];
  14. int edge[210][210];
  15. int cnt = 0;
  16.  
  17. int nx,ny;
  18. int vis[220];
  19. int cx[220],cy[220];
  20. int dx[220],dy[220];
  21.  
  22. int prime[maxn],primesize,phi[maxn];
  23. bool isprime[maxn];
  24. void getlist(int listsize)
  25. {
  26. memset(isprime,1,sizeof(isprime));
  27. isprime[1]=false;
  28. for(int i=2;i<=listsize;i++)
  29. {
  30. if(isprime[i])prime[++primesize]=i;
  31. for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++)
  32. {
  33. isprime[i*prime[j]]=false;
  34. if(i%prime[j]==0)break;
  35. }
  36. }
  37. }
  38.  
  39. void pre()
  40. {
  41. getlist(maxn-1);
  42. cin>>n;
  43. for(int i=1;i<=n; i++){
  44. int num;
  45. cin>>num;
  46. a[num] = 1;
  47. if(a[num-1]!=a[num]) b[num] = 1;
  48. else b[num] = 0;
  49. if(a[num]!=a[num+1]) b[num+1] = 1;
  50. else b[num+1] = 0;
  51. }
  52. for(int i=1; i<maxn; i++){
  53. if(b[i] == 1) point[++cnt] = i;
  54. }
  55. for(int i=1; i<=cnt; i++){
  56. if(point[i]%2 == 1) nx++,dx[nx] = point[i];
  57. else ny++,dy[ny] = point[i];
  58. }
  59. // cout<<nx<<" "<<ny<<endl;
  60. for(int i=1; i<=nx; i++){
  61. for(int j=1; j<=ny; j++){
  62. if(isprime[abs(dx[i] - dy[j])])
  63. edge[i][j] = 1;
  64. // cout<<dx[i]<<" "<<dy[j]<<endl;
  65. }
  66. }
  67. }
  68.  
  69. bool path(int u)
  70. {
  71. for(int i=1; i<=ny; i++){
  72. if(edge[u][i] && !vis[i]){
  73. vis[i] = 1;
  74. if(path(cy[i]) || cy[i] == -1){
  75. cx[u] = i;
  76. cy[i] = u;
  77. return 1;
  78. }
  79. }
  80. }
  81. return 0;
  82. }
  83.  
  84. int maxmatch()
  85. {
  86. int res = 0;
  87. CLR(cx,0xff);
  88. CLR(cy,0xff);
  89.  
  90. for(int i=1;i<=nx;i++){
  91. CLR(vis,0);
  92. res += path(i);
  93. }
  94. return res;
  95. }
  96.  
  97. int main()
  98. {
  99. // freopen("in.txt","r",stdin);
  100. pre();
  101. int ans = 0;
  102. int edgenum = maxmatch();
  103. // cout<<"edge "<<edgenum<<endl;
  104. // for(int i = 1; i<=nx; i++)
  105. // cout<<dx[i]<<" "<<dy[cx[i]]<<endl;
  106. ans += edgenum;
  107. ans += ((nx-edgenum)/2)*2;
  108. ans += ((ny-edgenum)/2)*2;
  109. if((nx-edgenum)%2 == 1) ans+=3;
  110. cout<<ans<<endl;
  111. return 0;
  112. }

Prime Flip AtCoder - 2689的更多相关文章

  1. [Arc080F]Prime Flip

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

  2. 【Atcoder】ARC 080 F - Prime Flip

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

  3. Prime Distance POJ - 2689 (数学 素数)

    The branch of mathematics called number theory is about properties of numbers. One of the areas that ...

  4. Prime Distance POJ - 2689 线性筛

    一个数 $n$ 必有一个不超过 $\sqrt n$ 的质因子. 打表处理出 $1$ 到 $\sqrt n$ 的质因子后去筛掉属于 $L$ 到 $R$ 区间的素数即可. Code: #include&l ...

  5. AT2689 [ARC080D] Prime Flip

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

  6. 【arc080F】Prime Flip

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

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

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

  8. AT2689 Prime Flip

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

  9. [atARC080F]Prime Flip

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

随机推荐

  1. CentOS7 使用yum命令安装Java SDK(openjdk)

    CentOS 6.X 和 7.X 自带有OpenJDK runtime environment  (openjdk).它是一个在linux上实现开源的java 平台. 安装方式: 1.输入以下命令,以 ...

  2. 【PMP】组织结构类型

    1.简单型 描述:人员并肩工作,所有者/经营者直接做出主要决定并监督执行. PM角色:兼职(协调员) PM权限:极少(无) 项目管理人员:极少(无) 资源可用性:极少(无) 项目预算管理人:负责人 2 ...

  3. 使用插件扩展Docker

    http://wwwbuild.net/dockerone/241249.html   Docker吸引我的,同时也是促使其成功的一个重要方面,是其开箱即用的特性. “开箱即用”是指什么呢?简单来说, ...

  4. OpenLayers4地图实例-功能齐全

    网址:http://api.rivermap.cn/openlayers4/map.min.html 标注 工具

  5. linux内核剖析(九)进程间通信之-信号signal

    信号及信号来源 什么是信号 信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应地采取一些行动.通常信号是由一个错误产生的.但它们还可以作为进程间通信或修改行为的一种方 ...

  6. CentOS 6.5 x64下网络配置

    一.自动获取IP地址 #dhclient 自动获取ip地址命令 #ifconfig 查询系统里网卡信息,ip地址.MAC地址 [root@CentOS6 ~]# vi /etc/sysconfig/n ...

  7. Android中的指纹识别

    转载请注明出处:http://blog.csdn.net/wl9739/article/details/52444671 评论中非常多朋友反映,依据我给出的方案,拿不到指纹信息这个问题,在这里统一说明 ...

  8. [svc]容器网络学习索引及网络监控

    整理的可能有些误失,抽时间在细细的分类完善下. 发现这篇对于网络从低到高层协议整理的还不错 每层都有一些有意思的话题 一些协议有一些设计上的弱点, 所以产生了种种的网络层安全问题 一般我们学一些 1, ...

  9. Java8新特性interface中的static方法和default方法

    static方法 java8中为接口新增了一项功能:定义一个或者更多个静态方法.用法和普通的static方法一样. 代码示例 public interface InterfaceA { /** * 静 ...

  10. nlp资料网站

    原文地址 http://blog.sina.com.cn/s/blog_574a437f01019poo.html 昨天实验室一位刚进组的同学发邮件来问我如何查找学术论文,这让我想起自己刚读研究生时茫 ...