题目:http://noi.ac/problem/32

从全是0和1的情况入手,可以像线段树一样分治下去,回到本层的时候就是左半部的右边是1,右半部的左边是0,把这两部分换一下就行。代价和时间一样是nlogn。

不全是0和1,可以像快速排序一样,先找一个基准,然后小于它的是0、大于它的是1,调用上一行的那个函数;本层弄好0和1以后,递归到全是0的部分和全是1的部分即可。这样代价和时间都是nlog^2n。

那个基准找得不好的话,一不小心就陷入死循环。所以自己还专门unique了一下,确保不会递归到自己。不过还是很心虚。

看别人有很好的写法,就是以基准(它的值也是中间位置的值,但不用unique)为mid,调用另一个和递归自己的范围就都可以是 l,mid-1 和 mid+1,r 了,这样就不会死循环。而且那个人没有返回那个0和1的边界,而是每次现从mid开始找;只是觉得这样写法扩展自己思路。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+;
int n,a[N],tmp[N],top;
bool b[N];
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
int deb;
int calc(int l,int r)
{
// if(deb<=30)printf("calc l=%d r=%d bl=%d\n",l,r,b[l]),deb++;
int p=r+;
for(int i=l;i<=r;i++) if(b[i]){p=i;break;}
if(p>r) return p-;//all 0
p=l-;
for(int i=l;i<=r;i++) if(!b[i]){p=i;break;}
if(p<l)return p;//all 1 int mid=l+r>>;
int p0=calc(l,mid),p1=calc(mid+,r);
// if(deb<=30)printf("calc:l=%d r=%d p0=%d p1=%d ",l,r,p0,p1);
if(p0+<p1)
{
printf("%d %d\n",p0+,p1);
for(int i=p0+,j=p1;i<j;i++,j--)
swap(a[i],a[j]),swap(b[i],b[j]);
} p=r+;
for(int i=l+;i<=r;i++) if(b[i]){p=i-;break;}
// if(deb<=30)printf("p=%d\n",p);
return p;
}
void solve(int l,int r)
{
if(l>=r)return;
bool flag=;
for(int i=l+;i<=r;i++) if(a[i]!=a[i-]){flag=;break;}
if(!flag)return; top=;
for(int i=l;i<=r;i++) tmp[++top]=a[i];
sort(tmp+,tmp+top+);
top=unique(tmp+,tmp+top+)-tmp-;//
int base=tmp[top>>];
// if(deb<=30)printf("base=%d\n",base); for(int i=l;i<=r;i++)
b[i]=(a[i]>base);//配合下取整的top
/* if(deb<=30)
{
printf("psol ");
for(int i=l;i<=r;i++)printf("%d ",b[i]);
printf("\n\n");
}
*/ // if(deb<=30)printf("solve l=%d r=%d\n",l,r);
int d=calc(l,r);
// if(deb<=30)printf("d=%d\n",d);
/*
if(deb<=30)
{
printf("csol ");
for(int i=l;i<=r;i++)printf("%d ",b[i]);
printf("\n\n");
}
*/
solve(l,d); solve(d+,r);
}
int main()
{
n=rdn();
for(int i=;i<=n;i++) a[i]=rdn();
solve(,n);
printf("-1 -1\n");
return ;
}

NOI.AC 32 Sort——分治的更多相关文章

  1. [NOI.AC#32]sort 构造

    链接 50分做法(只有0,1) 根据归并排序的思想,假设我们现在已经把 \(l\dots mid\) 和 \(mid+1\dots r\) 排好序 只要把左边连续的1和右边连续的0翻转即可 inlin ...

  2. noi.ac day1t3 Sort

    传送门 分析 快排的原理是以任意一个数为标准,然后把所有小于它的数换到它的左边,所有大于它的数换到它的右边.我们就使用快排的思路,分治整个区间.对于每个区间以排好序的这个数列的中间位置的值为标准,然后 ...

  3. noi.ac #32 快速排序归并排序应用

    \(des\) 给定长度为 \(n\) 的数组,要求翻转一段区间 \([l, r]\) 使其升序排列. 要求 \(\sum r - l + 1 <= 2e7\) \(sol\) 考虑快速排序,每 ...

  4. NOI.AC#2266-Bacteria【根号分治,倍增】

    正题 题目链接:http://noi.ac/problem/2266 题目大意 给出\(n\)个点的一棵树,有一些边上有中转站(边长度为\(2\),中间有一个中转站),否则就是边长为\(1\). \( ...

  5. NOI.AC#2007-light【根号分治】

    正题 题目链接:http://noi.ac/problem/2007 题目大意 \(n\)个格子排成一排,每个格子有一个\(0/1\)和一个颜色.开始每个格子都是\(0\),\(q\)次操作取反一个颜 ...

  6. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  7. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  8. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  9. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

随机推荐

  1. 首选项框架PreferenceFragment部分源代码分析

    由于要改一些settings里面的bug以及之前在里面有做过勿扰模式,准备对勿扰模式做一个总结,那先分析一下settings的源代码,里面的核心应该就是android3.0 上面的首选项框架Prefe ...

  2. 之前博客中的代码都放到github上

    之前一直把代码托管在taocode上,现在已经不能用了,所以把代码整理了一下,统一都放在gibhub上了. LALR(1)语法分析生成器:https://github.com/kiven-li/xby ...

  3. EasyNVR RTSP转RTMP-HLS流媒体服务器前端构建之_关于接口调用常见的一些问题(401 Unauthorized)

    在之前的博客<EasyNVR H5流媒体服务器方案架构设计之视频能力平台>中我们描述了EasyNVR的定位,作为一个能力平台来进行功能的输出: 也就是说,在通常情况下,我们将一套视频的应用 ...

  4. 关于TransactionScope 使用

    在去年的项目中使用了TransactionScope,现在总结下TransactionScope的使用说明 一.TransactionScope是.Net Framework 2.0之后,新增了一个名 ...

  5. sql server单引号和双引号的区别

    --当 SET QUOTED_IDENTIFIER 为 ON 时,标识符可以由双引号分隔,而文字必须由单引号分隔--当 SET QUOTED_IDENTIFIER 为 OFF(默认值)时,表达式中的文 ...

  6. iOS SQLite使用

    数据库的特征: 以一定方式存储在一起 能为多个用户分享 具有尽可能少的冗余代码 与程序彼此独立的数据集 SQLite SQLite是一个轻量级关系数据库,最初的设计目标是用于嵌入式系统,它占用资源非常 ...

  7. PYTHON加密解密字符串

    依赖包安装部分 安装依赖包: pip install pycryptodome 在你的python环境中的下图红框路径中找到 crypto 将其改成 Crypto 代码部分 #!/usr/bin/en ...

  8. python调试利器:最直观简洁的错误日志

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2018-08-30 17:12:27 # @Author : Sheldon (thi ...

  9. Java for LeetCode 090 Subsets II

    Given a collection of integers that might contain duplicates, nums, return all possible subsets. Not ...

  10. 【转载】帧缓冲驱动程序分析及其在BSP上的添加

    原文地址:(四)帧缓冲驱动程序分析及其在BSP上的添加 作者:gfvvz 一.BSP修改及其分析   1. BSP中直接配置的四个寄存器 S3C6410数据手册的第14.5部分是显示控制器的编程模型部 ...