CF1504D Flip the Cards(找规律+贪心)

题目大意:给你n张牌,正反面都有数字,保证所有牌上的数字在$[1,2n]$内且互不相同。你可以翻转任意张牌,接下来需要把牌按正面的数字从小到大排序,需要保证排序后牌背面的数字是从大到小。给出初始时牌的状态,问最少需要多少次翻转才能符合要求,如果一定达不到要求则输出-1。 n=1e5

限制关系是环,难以从前到后直接处理这个长度为2n的序列

套路1:把序列砍成一半

我们定义$a[i]$表示数$i$的牌背面的数字是多少。

多画几个例子容易发现,如果一张牌正反面都$\le n$或正反面都$>n$,一定不合法!因为数字各不相同,排的时候剩余的空不够!假设有一张牌的数字都$\le n$,那么在$[1,n]$内可用的其他位置为$n-2$个,却还有$n-1$张牌要占位置。都$>n$的情况是同一个道理

现在只考虑$[1,n]$,我们需要把$a[i]$划分成两个下降子序列!第一个序列i正面$a[i]$负面,第二个序列从后到前,a[i]反面i正面。

套路2:观察性质

如果$i$满足$min_{j\le i}(a[j]) > max_{j>i}(a[j])$,我们称$i$和$i+1$的间隔是一个间断,间断把序列分成数段,段和段之间的答案不会相互影响,因为段头可以接在任意一个子序列的末尾

单个段具有特殊性质!如果这段划分成两个下降子序列,那么划分的方式是唯一的

证明:

假设这一段是$[l,r]$,那么只有唯一的一个$x\in(l,r],a[x]>a[l]$

对于$i\in (l,r]$

1.要么存在$l\le j<i$,$a[j]<a[i]$,$i$和$j$一定不在一组

2.要么存在$i<k\le r$,$a[k]>a[i]$,$k$和$i$不在一组

对于$(l,x)$的位置,一定和l划分到一组。在这之后,l开头一组,x开头一组。现在需要证明$(x,r]$之间的划分方式唯一

如果$a[i]$小于l的序列的末尾元素,似乎可以把i分到l或者x的末尾。但它一定不满足性质1,则性质2成立,它必须和k不在同一组。如果k满足性质2,对应的位置是k',那么i,k,k'都不在同一组,一定不合法,因此k只能满足性质1,与i不在同一组。如果a[i]大于l的末尾元素,则只可能放在x的末尾。

当遍历到x+1是,l组的末尾(也就是x-1)满足性质2,x-1对应的k一定不和l一组,只能和x一组。归纳到(x,r]的其他位置,唯一确定了这一段的划分方式

综上,我们只需要关心l是正还是反就行了,正反两种情况讨论一下取最小值即可

 1 const int maxn=400000,N1=maxn+5; const int inf=0x3f3f3f3f;
2
3 int n;
4 template <typename _T> void read(_T &ret)
5 {
6 ret=0; _T fh=1; char c=getchar();
7 while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); }
8 while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
9 ret=ret*fh;
10 }
11 int oa[N1],ob[N1],a[N1], type[N1];
12 int sma[N1],smi[N1];
13
14 int mi[2];
15 int check(int l,int r,int p)
16 {
17 mi[p]=a[l]; mi[p^1]=inf; int ans=type[l]^p;
18 for(int i=l+1;i<=r;i++)
19 {
20 if(a[i]>max(mi[p],mi[p^1])) return -1;
21 if(mi[p]<mi[p^1]){
22 if(a[i]<mi[p]) mi[p]=a[i], ans+=type[i]^p;
23 else mi[p^1]=a[i], ans+=type[i]^p^1;
24 }else{
25 if(a[i]<mi[p^1]) mi[p^1]=a[i], ans+=type[i]^p^1;
26 else mi[p]=a[i], ans+=type[i]^p;
27 }
28 }
29 return ans;
30 }
31 int calc(int l,int r)
32 {
33 return min(check(l,r,1),check(l,r,0));
34 }
35 int solve()
36 {
37 int ans=0, tmp;
38 for(int i=1,j=1;i<=n;i++)
39 {
40 for(j=i;j<n&&smi[j]<=sma[j+1];j++);
41 tmp=calc(i,j); if(tmp==-1) return -1;
42 ans+=tmp;
43 i=j;
44 }
45 return ans;
46 }
47
48 int main()
49 {
50 scanf("%d",&n);
51 for(int i=1;i<=n;i++)
52 {
53 read(oa[i]), read(ob[i]);
54 if( (oa[i]<=n && ob[i]<=n) || (oa[i]>n && ob[i]>n) ){ puts("-1"); return 0; }
55 if(oa[i]<=n) a[oa[i]]=ob[i]; else a[ob[i]]=oa[i], type[ob[i]]=1;
56 }
57 smi[0]=inf;
58 for(int i=1;i<=n;i++) smi[i]=min(smi[i-1],a[i]);
59 for(int i=n;i>=1;i--) sma[i]=max(sma[i+1],a[i]);
60 int ans=solve();
61 printf("%d\n",ans);
62 return 0;
63 }

CF1504X Codeforces Round #712的更多相关文章

  1. Codeforces Round #712 (Div. 2)

    A. Déjà Vu 题意:就是问能否加上字母a,使得字符串不中心对称 思路:只有一种情况不能加入,就是全部是a,剩下的都可以满足,找a的位置就找哪个字母不是a,然后让它的对称位置是新加的这个a 代码 ...

  2. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  3. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  4. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  5. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  6. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  7. Codeforces Round #262 (Div. 2) 1003

    Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...

  8. Codeforces Round #262 (Div. 2) 1004

    Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...

  9. Codeforces Round #370 - #379 (Div. 2)

    题意: 思路: Codeforces Round #370(Solved: 4 out of 5) A - Memory and Crow 题意:有一个序列,然后对每一个进行ai = bi - bi  ...

随机推荐

  1. [LeetCode]13.罗马数字转整数(Java)

    原题地址: roman-to-integer 题目描述: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M ...

  2. Nginx兼容框架的pathinfo模式与URL重写

    几乎所有的框架(ThinkPHP,Zend Framework,CI,Yii,laravel等)都会使用URL重写或者pathinfo模式,使URL看起来更美观,比如可以隐藏掉入口文件,并且有利于搜索 ...

  3. VS2019配置eigen

    本文讲述如何在VS2019中配置eigen eigen版本:eigen-3.3.9 百度网盘地址:https://pan.baidu.com/s/1Bu5A58qV2n8doDs4NpPfJQ  提取 ...

  4. .NET 云原生架构师训练营(权限系统 系统演示 EntityAccess)--学习笔记

    目录 模块拆分 EntityAccess 模块拆分 EntityAccess 实体权限 属性权限 实体权限 创建 student https://localhost:7018/Student/dotn ...

  5. 强力推荐!五款能让你成为Excel“高手”的Excel插件

    excel是大家日常生活中经常用到一款表格软件,虽然软件本身的功能已经非常齐全了,但是插件可以进一步加强软件的功能,为用户提供更好的体验,提高工作效率,需要的用户快来看看吧. 1.Smartbi 首推 ...

  6. Centos6/7系统基础配置-从零到无

    转至:https://www.cnblogs.com/Pigs-Will-Fly/p/13855300.html 目录 前言 系统配置 文档作用 一.Centos 6.X 系列配置 1.1  主机名 ...

  7. redis面试1-33

    目录 1.Redis你比较熟吧,说说它机制为什么快? 2.redis是单线程吗? 3.为什么redis需要把所有数据放到内存中? 4.Redis的回收策略有哪些? 5.MySQL里有2000w数据, ...

  8. TensorFlow入门示例教程

    本部分的代码目前都是基于GitHub大佬非常详细的TensorFlow的教程上,首先给出链接: https://github.com/aymericdamien/TensorFlow-Examples ...

  9. js识别手机型号做业务判断

    navigator为Window对象的一个属性,指向了一个包含浏览器相关信息的对象. navigatot中包含了一些常用到的属性,如: navigator.appVersion 浏览器的版本号 nav ...

  10. mybatis介绍--基于个人学习JavaWeb的使用

    mybatis介绍 该博文放在javaWeb系列下,目的是记录我们javaWeb阶段所学的知识 @time=2022/3/11/11:52(最近休息玩了两天,今天重新启动生活) 一.mybatis发展 ...