题目: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. 利用xlrd模块实现Python读取Excel文档

    # -*- coding: cp936 -*- #python读取excel import xlrd def main(): xls=xlrd.open_workbook("d:\\11.x ...

  2. mysql日期格式转化

    select DATE_FORMAT( '20170701', '%Y-%m-%d'); 先挖坑

  3. 4.锁--并行编程之条件变量(posix condition variables)

    在整理Java LockSupport.park()的东东.看到了个"Spurious wakeup".又一次梳理下. 首先来个<UNIX环境高级编程>里的样例: [c ...

  4. 【Caffe】利用log文件绘制loss和accuracy(转载)

    (原文地址:http://blog.csdn.net/liuweizj12/article/details/64920428) 在训练过程中画出accuracy 和loss曲线能够更直观的观察网络训练 ...

  5. java log4j 日志文件

    开发中经常会用到log日志文件,根据业务需要可能不产生很大日志文件给维护和[排错带来了麻烦.所以我们希望能够每天或每个月产生一个日志文件,这样文件不至于过大. 或者根据日志文件大小来判断,超过规定大小 ...

  6. SSIS

    http://www.cnblogs.com/codefish/category/557802.html

  7. EasyDSS RTMP流媒体服务器的HTTP接口query url的C++实现方法

    EasyDSS支持HTTP GET接口访问,我们需要获取url的各种参数信息 比如http://ip:port/action?a=1&b=2&c=3 我们需要知道对应的a.b.c的值 ...

  8. Grunt 学习笔记【2】---- 配置和创建任务

    本文主要讲Grunt任务配置. 说明:本文所有示例都基于Grunt 0.4.5版本. 一 说明 使用Grunt实现项目的打包等工程化工作,实际上是通过Grunt提供的机制和插件,配置一个个任务(例如: ...

  9. mybatis 执行查询时报错 【Error querying database. Cause: java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: 】

    org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.sql.SQLE ...

  10. 【shell】awk引用外部变量

    在使用awk的过程中,经常会需要引用外部变量,但是awk需要使用单引号将print包起来,导致print后的$引用无效,可以采用下面的方式 例如: #!/bin/bash a="line1 ...