zoukankan      html  css  js  c++  java
  • [***]HZOJ 柱状图

    神仙题。

    作者的正解:

    算法二:对于60%的数据:考虑直接枚举屋顶的位置,总花费与屋顶的高度的关系是一个单峰函数,,我们可以用三分法三分屋顶的高度. 时间复杂度O(n2*logn)。

     

    算法三:对于100%的数据:  我们枚举屋顶位置再三分高度的做法,复杂度的瓶颈在于花费的计算。假设屋顶在i处,高度为hi,如果j<i,hj-j=hi-i ; 如果j>i,hj+j=hi+i。

    根据权值排序,建立树状数组来解决权值与i的权值的关系,用两个树状数组维护。时间复杂度O(n(logn)(logv),V为屋顶的高度

    对于60%的数据大概有两种做法:

    1.如作者题解,说的挺清楚的。

    2.考虑对于一个确定的位置作为屋顶,那么屋顶的高度是确定的,证明以后再说。将每个点的高度加上到屋顶的距离,高度为之后序列的中位数,所以就可以模拟退火了。

    对于100%的数据:

    1.模拟退火(没脸)。

    2.枚举屋顶,三分高度,然后主要的优化就是在计算花费上。可以用两个树状数组维护。

    由于时间比较紧剩下的先咕掉了……

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #define int LL
     6 #define LL long long
     7 #define MAXN 100010
     8 #define reg register
     9 #define con const
    10 using namespace std;
    11 struct node
    12 {
    13     int val,id;
    14     friend bool operator < (node a,node b)
    15     {return !(a.val^b.val)?a.id<b.id:a.val<b.val;}
    16 }al[MAXN],ar[MAXN];
    17 int n,a[MAXN],maxh,rkl[MAXN],rkr[MAXN];
    18 #define lowbit(x) ((x)&(-(x)))
    19 struct bit
    20 {
    21     int C[MAXN],num[MAXN];
    22     void add(reg int x,reg con int y,reg con int z)
    23     {while(x<=n){C[x]+=y;num[x]+=z;x+=lowbit(x);}}
    24     pair<int,int> ask(reg int x)
    25     {
    26         int sum=0,nnum=0;
    27         while(x)
    28         {
    29             sum+=C[x];
    30             nnum+=num[x];
    31             x-=lowbit(x);
    32         }
    33         return make_pair(sum,nnum);
    34     }
    35 }le,re;
    36 __attribute((always_inline))int get(reg con int x,reg con int maxh)
    37 {
    38     int ans=0;
    39     ans+=abs(maxh-a[x]);
    40     int pos=upper_bound(al+1,al+n+1,(node){maxh-x,x})-al-1;
    41     pair<int,int> tem=le.ask(pos);
    42     ans+=tem.second*(maxh-x)-tem.first;
    43     pair<int,int> tem2=le.ask(n);
    44     ans+=tem2.first-tem.first-(tem2.second-tem.second)*(maxh-x);
    45     pos=upper_bound(ar+1,ar+n+1,(node){maxh+x,x})-ar-1;
    46     tem=re.ask(pos);
    47     ans+=tem.second*(maxh+x)-tem.first;
    48     tem2=re.ask(n);
    49     ans+=tem2.first-tem.first-(tem2.second-tem.second)*(maxh+x);
    50     return ans;
    51 }
    52 __attribute((always_inline))void read(int &s)
    53 {
    54     s=0;
    55     reg int f=1;reg char a=getchar();
    56     while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
    57     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    58     s*=f;
    59 }
    60 signed main()
    61 {
    62     read(n);
    63     int ans=0x7ffffffffffff;
    64     for(reg int i=1;i<=n;++i)
    65     {
    66         read(a[i]);
    67         al[i].val=a[i]-i,al[i].id=i;
    68         ar[i].val=a[i]+i,ar[i].id=i;
    69     }
    70     sort(al+1,al+n+1);
    71     sort(ar+1,ar+n+1);
    72     for(reg int i=1;i<=n;++i)rkl[al[i].id]=i,rkr[ar[i].id]=i;
    73     for(reg int i=1;i<=n;++i)re.add(rkr[i],a[i]+i,1);
    74     for(reg int i=1;i<=n;++i)
    75     {
    76         re.add(rkr[i],-a[i]-i,-1);
    77         int l=max(i,n-i+1),r=1e9,ml,mr;
    78         ans=min(ans,get(i,l));
    79         while(r>l+1)
    80         {
    81             int mid=(l+r)>>1;
    82             ml=mid-1,mr=mid;
    83             int ans1=get(i,ml),
    84                 ans2=get(i,mr);
    85             if(ans1<ans2)r=mid;
    86             else l=mid;
    87             ans=min(ans,ans1);
    88             ans=min(ans,ans2);
    89             if(!(ml^l)&&!(mr^r))break;
    90         }
    91         le.add(rkl[i],a[i]-i,1);
    92     }
    93     printf("%lld
    ",ans);
    94 }
    View Code
  • 相关阅读:
    小伙子的毕业设计
    mongoDB
    Java面试题笔试题收集
    react-router4 介绍
    React 组件间通信 总结
    react ajax
    react应用(基于react脚手架)
    React 之 组件生命周期
    组件收集表单数据
    组件的组合使用
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11318851.html
Copyright © 2011-2022 走看看