题目: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. android之Context对各种服务的管理

    经常,当我们须要用到服务的时候能够通果Context来获取:Context.getSystemService(name):比方:当我们想知道当前电话状态(来电/去电/sim卡状态等)时候,我们能够通过 ...

  2. 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  3. Top 10 Open Source Bug Tracking System系统

    Bugzilla http://www.bugzilla.org/ Mantis php http://www.mantisbt.org/ Trac Python also provides wiki ...

  4. 20-ab压力测试及nginx性能统计模块

    一:找到apache ab模块. ab -c 1000 -n 50000 http://127.0.0.1/index.html 查看信息: 超过1024个线程 出现错误,说打开文件太多了.cket: ...

  5. Android 繪圖白板元件,有畫筆和板擦的功能 (转)

    package com.example.drawboard; import java.util.ArrayList; import java.util.List; import android.con ...

  6. java 面试总结

    1.static变量与实体变量的差别? static是静态变量,static能够通过类名直接訪问 内存方面的不同:static在定义的时候jvm就会分配空间, 而实体变量仅仅有在创建对象的时候才会去分 ...

  7. gdb ../sysdeps/i386/elf/start.S: No such file or directory

    使用 gdb 调试的时候 输入 l 之后出现下列信息 (gdb) l 1 ../sysdeps/i386/elf/start.S: No such file or directory. in ../s ...

  8. Vue中表单校验

    1.安装校验插件vee-validate npm install vee-validate --save 2.在main.js中引用插件 // 表单校验 import VeeValidate, { V ...

  9. Spring和ActiveMQ整合的完整实例

     Spring和ActiveMQ整合的完整实例 前言 这篇博文,我们基于Spring+JMS+ActiveMQ+Tomcat,做一个Spring4.1.0和ActiveMQ5.11.1整合实例,实现了 ...

  10. 九度OJ 1037:Powerful Calculator(强大的计算器) (大整数运算)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1821 解决:528 题目描述: Today, facing the rapid development of business, SJTU ...