zoukankan      html  css  js  c++  java
  • UER#7 T2

    题意:给定n个数,对于2到n,分别输出一个答案。答案定义为:对于当前的数k,在原数组中找一个长度为k的区间,使得区间最值之差最小,输出差值。注意,差值允许5%的误差。

    很少看见近似算法的题啊。。跪烂VFK大爷。

    首先可以注意到的是,答案一定是单增的。我们再发现,随着1.05指数不断增加,之后肯定会有质的飞跃(毕竟是指数函数),也就是说,到时候一定有一大段区间的答案都是同一个数。所以我们只要分别找出每一个段的答案就好了。段数大概是log的(不会证,凭感觉吧。。。

    先把2和n的答案计算出来,然后分治下去。如果当前分治的区间,左端点的答案误差范围已经和右边答案的误差范围相交,说明夹在他们中间的数们答案全一样,随便选一个复制给他们就好了。

    时间复杂度O(nlogn)。跪烂。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define INF 1e9
     5 #define eps 1e-5
     6 inline int read(){
     7     int x=0,f=1; char a=getchar();
     8     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
     9     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
    10     return x*f;
    11 }
    12 int n,mx[N][20],mn[N][20],ans[N],Log[N];
    13 inline int Max(int x){
    14     return (int)((double)x*1.05+eps);
    15 }
    16 inline int Min(int x){
    17     return (int)((double)x*0.95+1-eps);
    18 }
    19 inline void pre(){
    20     Log[0]=-1; for(int i=1;i<=n;i++) Log[i]=Log[i>>1]+1;
    21     for(int i=1;i<=18;i++)
    22         for(int j=1;j<=n;j++){
    23             mx[j][i]=max(mx[j][i-1],mx[min(n,j+(1<<(i-1)))][i-1]);
    24             mn[j][i]=min(mn[j][i-1],mn[min(n,j+(1<<(i-1)))][i-1]);
    25         }
    26 }
    27 inline int qmx(int l,int r){
    28     return max(mx[l][Log[r-l+1]],mx[r-(1<<Log[r-l+1])+1][Log[r-l+1]]);
    29 }
    30 inline int qmn(int l,int r){
    31     return min(mn[l][Log[r-l+1]],mn[r-(1<<Log[r-l+1])+1][Log[r-l+1]]);
    32 }
    33 inline void cal(int x){
    34     ans[x]=INF;
    35     for(int i=1;i<=n-x+1;i++) ans[x]=min(ans[x],qmx(i,i+x-1)-qmn(i,i+x-1));
    36 }
    37 void dc(int l,int r){
    38     if(r-l<=1) return;
    39     if(Max(ans[l])>=Min(ans[r])){
    40         int tmp=Max(ans[l]);
    41         for(int i=l+1;i<r;i++) ans[i]=tmp;
    42         return;
    43     }
    44     int mid=(l+r)>>1;
    45     cal(mid);
    46     dc(l,mid); dc(mid,r);
    47 }
    48 int main(){
    49     n=read(); for(int i=1;i<=n;i++) mx[i][0]=mn[i][0]=read();
    50     pre();
    51     cal(2); cal(n); dc(2,n);
    52     for(int i=2;i<=n;i++) printf("%d
    ",ans[i]);
    53     return 0;
    54 }
  • 相关阅读:
    Win10 注册IIs4.0的解决方案
    Win10 注册IIs4.0的解决方案
    Methods for Using Message Queuing Telemetry Transport for Sensor Networks to Support Sleeping Devices
    Win10 注册IIs4.0的解决方案
    真正聪明的人,为什么从不去社交?
    真正聪明的人,为什么从不去社交?
    真正聪明的人,为什么从不去社交?
    真正聪明的人,为什么从不去社交?
    真正聪明的人,为什么从不去社交?
    真正聪明的人,为什么从不去社交?
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6279550.html
Copyright © 2011-2022 走看看