ssrf-攻擊未授權redies
阿新 • • 發佈:2021-12-31
決策單調性的另一種寫法。似乎仍然可以使用斜率優化但我沒去寫。
方程不重要,我的那個“方差一瞥”已經寫得很清楚了,說一下決策單調性的第二種寫法吧。這種寫法適用於:
\[f[x]=\min\limits_{i=0}^{x-1}\{g(i)+w[i,x]\} \]其中\(g(i)\)是一個與\(f[i]\)無關的函式。可以發現這個過程可以是離線的,畢竟先求誰再求誰對答案沒有影響。於是就可以考慮分治。
用\(solve(wl,wr,l,r)\)來表示我們希望求區間[wl,wr]的答案,它們決策點的區間為[l,r]。我們可以考慮暴力求出\(\frac{wl+wr}{2}\)的答案,由於決策單調不減,那麼[wl,mid-1]的決策點範圍肯定是[l,k(mid)],右邊同理。由於這種寫法具有分治特性,它的複雜度大概是\(O(NlogN)\)
另外這種題目也要滿足那個奇怪不等式才能生效。本題中你會發現它的w函式仍然是個開口朝上的二次函式,套用van具裝箱的解釋它也是滿足條件的。
一如既往,萬事勝意#include<cstdio> #include<cstring> //#define zczc #define int long long const int N=3010; inline void read(int &wh){ wh=0;int f=1;char w=getchar(); while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();} while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();} wh*=f;return; } int m,n,a[N],s[N],f[N][N]; void solve(int x,int wl,int wr,int l,int r){ if(wl>wr)return; int mid=wl+wr>>1,pl; for(int i=l;i<=r&&i<=mid;i++){ int now=f[x-1][i]+(s[mid]-s[i])*(s[mid]-s[i]); if(now<f[x][mid])f[x][mid]=now,pl=i; } solve(x,wl,mid-1,l,pl); solve(x,mid+1,wr,pl,r); } signed main(){ #ifdef zczc freopen("in.txt","r",stdin); #endif read(m);read(n);memset(f,0x3f,sizeof(f)); for(int i=1;i<=m;i++)read(a[i]),s[i]=s[i-1]+a[i]; for(int i=1;i<=m;i++)f[1][i]=s[i]*s[i]; for(int i=2;i<=n;i++)solve(i,1,m,0,m-1); printf("%lld",-s[m]*s[m]+n*f[n][m]); return 0; }