[BZOJ5125]小さなQ本棚(除算の決定単調さをとDP + + + Moのフェンウィックツリーチームを征服?)

\(O(N ^ 2K) \) 比較ミス

\(DP [I] [J] = \分\ limits_ {K <I}(DP [K] [J-1] + W(K + 1、I))\)

\(W \)逆順の数です。

意思決定単調で見つかったテーブルを再生します。

しかし、我々はすぐに逆に動作していないので、単調なキューの数をカウント見つけることができません。

格差を考えると征服、

\((L、R、解く )L、R、Kを\) の部分計算する表す\を([L、R&LT] \) 決定点はに位置してもよい\([L、R] \ ) 、内部計算されたので、激しいです\(中旬\) 最適な意思決定ポイントです\(のP- \)再帰DPの両側に、

/*
@Date    : 2019-08-16 21:14:43
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define int long long
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
const int N=4e4+7;
int n,K,sum;
int c[N],a[N],f[N][11];
void add(int k,int x){for(;k<=n;k+=k&-k)c[k]+=x;}
int qry(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
int L,R;
void move(int l,int r){
    while(L<l)sum-=qry(a[L]-1),add(a[L++],-1);
    while(L>l)sum+=qry(a[L-1]-1),add(a[--L],1);
    while(R<r)sum+=R-L+1-qry(a[R+1]),add(a[++R],1);
    while(R>r)sum-=R-L+1-qry(a[R]),add(a[R--],-1);
}
void solve(int l,int r,int L,int R,int now)
{
    if(l>r)return;
    int mid=(l+r)>>1,p=L;
    for(int i=L;i<=min(mid-1,R);++i)
    {
        move(i+1,mid);
        if(f[i][now-1]+sum<f[mid][now])f[mid][now]=f[i][now-1]+sum,p=i;
    }
    solve(l,mid-1,L,p,now);
    solve(mid+1,r,p,R,now);
}
signed main(void)
{
    n=gi,K=gi;
    for(int i=1;i<=n;++i)a[i]=gi;
    memset(f,127,sizeof f);
    L=1,R=0;
    for(int i=1;i<=n;++i)move(1,i),f[i][1]=sum;
    for(int i=2;i<=K;++i)solve(1,n,1,n,i);
    pi(f[n][K]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/LLCSBlog/p/11366472.html