zoukankan      html  css  js  c++  java
  • [noi32]sort

    先解释一下checker.cpp,它的判定标准是2e7,即答案超过2e7就认为代价过大了。

    首先,很容易想到的办法是直接对其快排,从外到内交换区间即可,然而这样会被邪恶的出题人给卡掉(当然其实随便一组大数据都能卡)。

    由于一次操作可以翻转而不仅仅是交换,所以要将一个区间分成两块仅仅需要经左右两个区间都分成两块后对中间进行一个翻转即可。

    来分析一下这种做法的代价:计将一个长度为l区间分成两块的代价为T(l),那么有递推式T(l)=2T(l/2)+l,即$T(l)=l\ log_{2}l$。然后计将一个长度为l的区间排好序的代价为T’(l),有递推式$T'(l)=2T'(l/2)+T(l)=2T'(l/2)+l\ log_{2}l$,解得$T'(l)=l\ log_{2}^{2}l$,即总代价(或者说总时间复杂度)为$o(l\ log_{2}^{2}l)$,看上去似乎差不多就是2e7,但实际上是可以通过的

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mid (l+r>>1)
     4 map<int,int>mat;
     5 int n,a[50001],b[50001];
     6 void rev(int l,int r,int k){
     7     if (l==r)return;
     8     rev(l,mid,k);
     9     rev(mid+1,r,k);
    10     int i=mid+1,j=mid;
    11     while ((i>l)&&(a[i-1]>k))i--;
    12     while ((j<r)&&(a[j+1]<=k))j++;
    13     if (i<j)printf("%d %d\n",i,j);
    14     reverse(a+i,a+j+1);
    15 }
    16 void kspx(int l,int r){
    17     if (l==r)return;
    18     rev(l,r,mid);
    19     kspx(l,mid);
    20     kspx(mid+1,r);
    21 }
    22 int main(){
    23     scanf("%d",&n);
    24     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    25     memcpy(b,a,sizeof(b));
    26     sort(b+1,b+n+1);
    27     for(int i=1;i<=n;i++)mat[b[i]]=i;
    28     for(int i=1;i<=n;i++)a[i]=mat[a[i]]--;
    29     kspx(1,n);
    30     printf("-1 -1");
    31 }
    View Code
  • 相关阅读:
    Leetcode: Largest Rectangle in Histogram
    Leetcode: Sum Root to Leaf Numbers
    Leetcode: LRU Cache
    Leetcode: Candy
    Leetcode: Interleaving String
    Leetcode: Implement strStr()
    Leetcode: Gray Code
    Leetcode: Restore IP addresses
    Leetcode: Median of Two Sorted Arrays
    Leetcode: Pow(x, n) and Summary: 负数补码总结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11272212.html
Copyright © 2011-2022 走看看