タイトル
効果の対象に
すべてのために、配列を与える\(IN K \ [1、N-] \) 、長シーク\(K \) 、最大優先度の値の配列を、重み値\(A_1、A_2 + A_3 -... \午後a_k \)
歴史上のものがたり
この質問は明らかに権利をバックパックすることができます......
そう......それは直接、バックパック
、私は分裂を考えると征服ゲームが、双方一緒にはとても暴力的な直接の再生を、非常に遅いです。
正解
問題のセグメントツリーアプローチソリューションは、本当に理解していない見られています。
だから私は、分割統治の方法を言います。
最初の問題の結論に溶液がある:\(K \)サブシーケンスがなければならない(K-2 \)\挿入された2つのシーケンス番号。
挿入するために覚えているだけではなく、左右の延長に。
なぜ?反対の証拠を考慮していない場合、つまり、\(K-2 \)数列の複数を除去し、その後、複数の番号を挿入します。これは、効果的に対応する(KX \)\の状態にわたって転送、\(X> 2 \) 。
だから我々は唯一のことを証明する必要があります\(K-2 \)以前より良いよりも上で転送するための場所から転送します。
仮定\(K-3 \) (他の場合と同様)から転送します。
我々は、(K-2 \)\配列挿入配列の\(X \)と\(Y \) 、次いで、全配列がいくつかの部分に分割されている\(AxByC \)の正しい値(\ \のPMのxBを\ Y-PM + C \) (私たちが関係する必要はありません\(X \)をして、\(のy \)は、正または負である\(Bの\)は裏返しにするキャレットの後、元の貢献です)。
\(K-3 \)に挿入された配列\(X \)と\(Y \)と\(Z \) (我々は仮定\(X \)と\(Y \)同じ挿入位置)に:\ (AxByDzE \)の右側の値、(\ \のPMのxBの\の午後
Y + D \のPM ZE \)は前半部分的に相殺比較、それはなる(C \)を\と\(Dの\のPM ZE \ )
彼らは、全体として見ることができます。より良い後者の場合、それは確かに代替する前になります\(C \) 。だから、かつてのいくつかは優れています。
このカードは以上です。
その後、パーティションを検討してください。分割統治の焦点は、2つの間隔をマージについての答えです。
考えてみましょう\(S \)をするために転写した(S + 2 \)を\。セットアップ転送\(S \)で左\(S_1 \)で右に1、\(S_2 \)ヶ月。
カテゴリー話と新たに挿入されたを参照してくださいには、次の3つの条件があるどちら側に2点を置きます:
- 左\(\ S_1 + 2) 、右\(S_2 \) 。
- 左\(\ S_1 + 1) 、右\(S_2 + 1 \)
- 左\(S_1 \) 、右\(S_2 + 2 \) 。
上記の結論によると、いずれの場合においても周りも問題ありません。問題は、第二のケースということです。
ですので\(+ 1 \)ように、結論は使用できません。
しかし、私たちが発見、左の中で\(S1 \)または右\(S2 \)内の各プラグの状態、実際には、左の上で考えることができる\(S1 + 1 \)または右\(S2 + 1 \)の状態インチ すなわち、\(S1 + 1 \)は以上の状態であり、\は(S1 \)の状態遷移を越えて挿入されています。
したがって、この操作は効果がありません。
コード
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#define N 100010
int n,a[N];
int _fmn[N],_fmx[N];
int gmn[N],gmx[N];
inline int at(int *a,int x){return x?a[x]:0;}
void dfs(int l,int r){
int *fmn=_fmn+l-1,*fmx=_fmx+l-1;
if (l==r){
fmn[1]=fmx[1]=a[l];
return;
}
int mid=l+r>>1;
dfs(l,mid),dfs(mid+1,r);
int *lmn=_fmn+l-1,*lmx=_fmx+l-1,*rmn=_fmn+mid,*rmx=_fmx+mid,s1=0,s2=0;
for (int i=2;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MIN;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmx,s1)-at(rmn,s2+2):at(lmx,s1)+at(rmx,s2+2));
if (tmp>v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmx,s1+1)-at(rmn,s2+1):at(lmx,s1+1)+at(rmx,s2+1));
if (tmp>v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmx,s1+2)-at(rmn,s2):at(lmx,s1+2)+at(rmx,s2));
if (tmp>v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmx[i]=v;
s1=ts1,s2=ts2;
}
s1=0,s2=0;
for (int i=2;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MAX;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmn,s1)-at(rmx,s2+2):at(lmn,s1)+at(rmn,s2+2));
if (tmp<v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmn,s1+1)-at(rmx,s2+1):at(lmn,s1+1)+at(rmn,s2+1));
if (tmp<v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmn,s1+2)-at(rmx,s2):at(lmn,s1+2)+at(rmn,s2));
if (tmp<v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmn[i]=v;
s1=ts1,s2=ts2;
}
if (lmx[1]>rmx[1])
s1=1,s2=0,gmx[1]=lmx[1];
else
s1=0,s2=1,gmx[1]=rmx[1];
for (int i=3;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MIN;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmx,s1)-at(rmn,s2+2):at(lmx,s1)+at(rmx,s2+2));
if (tmp>v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmx,s1+1)-at(rmn,s2+1):at(lmx,s1+1)+at(rmx,s2+1));
if (tmp>v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmx,s1+2)-at(rmn,s2):at(lmx,s1+2)+at(rmx,s2));
if (tmp>v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmx[i]=v;
s1=ts1,s2=ts2;
}
if (lmn[1]<rmn[1])
s1=1,s2=0,gmn[1]=lmn[1];
else
s1=0,s2=1,gmn[1]=rmn[1];
for (int i=3;i<=r-l+1;i+=2){
int ts1,ts2,v=INT_MAX;
if (s2+2<=r-mid){
int tmp=(s1&1?at(lmn,s1)-at(rmx,s2+2):at(lmn,s1)+at(rmn,s2+2));
if (tmp<v)
v=tmp,ts1=s1,ts2=s2+2;
}
if (s1+1<=mid-l+1 && s2+1<=r-mid){
int tmp=(s1+1&1?at(lmn,s1+1)-at(rmx,s2+1):at(lmn,s1+1)+at(rmn,s2+1));
if (tmp<v)
v=tmp,ts1=s1+1,ts2=s2+1;
}
if (s1+2<=mid-l+1){
int tmp=(s1+2&1?at(lmn,s1+2)-at(rmx,s2):at(lmn,s1+2)+at(rmn,s2));
if (tmp<v)
v=tmp,ts1=s1+2,ts2=s2;
}
gmn[i]=v;
s1=ts1,s2=ts2;
}
for (int i=1;i<=r-l+1;++i)
fmn[i]=gmn[i],fmx[i]=gmx[i];
}
int main(){
freopen("pe.in","r",stdin);
freopen("pe.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
dfs(1,n);
for (int i=1;i<=n;++i)
printf("%d ",_fmx[i]);
return 0;
}
概要
結論は推測に頼ることです......