Wooden_Raft problem solution

Wooden_Raft problem solution

Portal
exams, the exam just does not come out hard, do not have time to do other topic,Sick to death of me.
This is very bad do things in general practice only two thing:
1. greedy fucks.
2. fixed one-dimensional.
Enumeration, enumeration of course not engage in one-dimensional y, and then choose the wood section was changed to x y
First we> = y wood can be determined how many y constitute,
then set \ (x \ in [ky, ky + y) \) , we can choose> = ky wood which is cut into a length of x,
we greedily as in the case does not interfere with the choice of y, y% NATURAL selected from the greatest.
We discuss below the cut two x two situations :( Why? Nonsense, To y little interference, but also x as large as possible, not / could only cut a small x-Well)
1. From a piece of wood inside cut two x (a likely occurrence a particularly long wood)
2. from the wood two different cross-sectional views of two long within the range X
3. the wood from two different two truncated range the longest z x (a timber in the \ ([ky, ky + y ) \) inside, in the other \ ([ky + y, \
infty) \) time complexity \ (O (\ sum_ {i = 1} ^ {maxx } maxx / i) = O (maxx log maxx) \)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e5+6;
int n,t,ky,val,maxx=-1,pre_num,num[N],v[N],pre[N];
ll ans,k,sum=0;
inline int read(){
    int T=0,F=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
    while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
    return F*T;
}
struct Pair{
    int mod,w;
    Pair(int x=-1,int y=-1){mod=x,w=y;}
    bool operator < (const Pair &a) const {return mod!=a.mod?mod<a.mod:w<a.w;}
};
struct xx{
    Pair x,y;
    void update(Pair z){y=max(y,min(x,z)),x=max(x,z);}
};
void Max(ll p,ll q){ans=max(ans,(p<2ll?0ll:p*q));}
int main(){
    n=read();
    for(int i=1;i<=n;++i) t=read(),++v[t],maxx=max(maxx,t);
    for(int i=maxx;i>=0;--i) num[i]=num[i+1]+v[i];
    t=0;
    for(int i=0;i<=maxx;++i){
        if(v[i]) t=i;
        pre[i]=t;
    } 
    for(int y=2;y<=maxx;++y){
        sum=0,ky=maxx+1; xx tmp;
        for(int i=y;i<=maxx;i+=y) sum+=num[i];//截得出sum根y
        for(int i=maxx/y;i>=0;--i){
            val=pre[ky-1],pre_num=(tmp.x.mod>=0)+(tmp.y.mod>=0),t=i*y;
            //val:目前范围中的最大值
            if(val>=t){
                tmp.update((Pair){val%y,val});
                if(v[val]==1) val=pre[val-1];
                if(val>=t) tmp.update((Pair){val%y,val});
            }//更新最大值,次大值
            if(tmp.x.mod>=0) Max(min((ll)(t+tmp.x.mod)>>1,sum-i),y);
            //从一根木头里截
            if(tmp.y.mod>=0){
                Max(min((ll)t+tmp.y.mod,sum-i-i),y);
                //两根木头里截次长
                if(pre_num+(tmp.x.w<ky)>1) Max(min((ll)t+tmp.x.mod,sum-i-i-1),y);
                //两根木头里最次长
            }
            ky=t;
        }
    }
    printf("%lld\n",ans);
    return 0;
} 

Guess you like

Origin www.cnblogs.com/ljk123-de-bo-ke/p/11741736.html