[ 決策單調性 分治 ] LOJ#535 花火

題解

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
inline char nc() {
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x) {
    char c=nc();
    for(;c<'0'||c>'9';c=nc());
    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
const int N=300010;
const int M=7000000;
int k,n,m,x;
int a[N];
int Rt[N],c[M],ls[M],rs[M],num;
int s[N];
int b[N],d[N],l1,l2;
int Ans;
ll sum;
void Update(int& x,int y,int l,int r,int z) {
    x=++num;
    c[x]=c[y]+1;
    if(l==r)return;
    int Mid=l+r>>1;
    if(z<=Mid) rs[x]=rs[y],Update(ls[x],ls[y],l,Mid,z);
        else ls[x]=ls[y],Update(rs[x],rs[y],Mid+1,r,z);
}
int Query(int x,int y,int l,int r,int L,int R) {
    if(l>R||r<L) return 0;
    if(l>=L&&r<=R) return c[y]-c[x];
    int Mid=l+r>>1;
    return Query(ls[x],ls[y],l,Mid,L,R)+Query(rs[x],rs[y],Mid+1,r,L,R);
}
int Get(int l,int r) {
    return Query(Rt[l],Rt[r-1],1,n,a[r],a[l])+Query(Rt[l],Rt[r-1],1,n,a[r],a[l])+(a[l]<a[r]?-1:1);
}
void Solve(int l,int r,int L,int R) {
    if(l>r)return;
    int Mid=l+r>>1,pos=L,mx=-1;
    for(int i=L;i<=R;i++) 
        if(b[i]<d[Mid]) {
            int t=Get(b[i],d[Mid]);
            if(t>mx)mx=t,pos=i;
        }
    Ans=max(Ans,mx);
    Solve(l,Mid-1,L,pos);Solve(Mid+1,r,pos,R);
}
void Update(int x) {
    for(;x<=n;x+=x&-x) ++s[x];
}
int Query(int x) {
    int Ans=0;
    for(;x;x-=x&-x) Ans+=s[x];
    return Ans;
}
int main() {
    Read(n);
    for(int i=1;i<=n;i++) {
        Read(x);a[i]=x;
        Update(Rt[i],Rt[i-1],1,n,x);
        if(x>a[b[l1]]) b[++l1]=i;
        while(l2&&a[d[l2]]>x) l2--;d[++l2]=i;
    }
    int t=0;
    Solve(1,l2,1,l1);
    for(int i=n;i;i--) sum+=Query(a[i]),Update(a[i]);
    cout<<sum-max(Ans-1,0)<<endl;
    return 0;
}
發佈了288 篇原創文章 · 獲贊 104 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章