bzoj4504 K strings (chairman tree + heap)

Very similar to bzoj2006 .
It's just that the interval sum is difficult to calculate this time, and we need to build a chairman tree to find it.
Each leaf node x of rt[i] represents the answer when the right endpoint is i and the left endpoint is x.
Each node needs to maintain the maximum value of the interval and the location of the maximum value.
We have two operations, interval addition and query interval maximum.
The chairman tree of interval addition is more troublesome. It is too slow to create a new node when delegating.
We can consider marking permanent. Do not drop the mark.
Then it's good to use a heap to maintain greed for a problem like the super piano.
Or you can delete the maximum value each time.
the complexity O ( ( n + K ) l O g n )

I've been smitten by noi linux recently o(╥﹏╥)o
I'm finally going to shoot ♪(^∇^*)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1LL<<60
#define N 100010
#define pa pair<ll,int>
inline char gc(){
    static char buf[1<<16],*S,*T;
    if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
    return x*f;
}
int n,K,rt[N],owo=0;
struct node{
    pa x;ll tag;int ls,rs;//x.fir->mx,不考虑祖先懒标记的区间最大值,考虑自己。x.sec->mxid
}tr[N*60];
map<int,int>lst;
struct data{
    int l,r,x;pa val;
    data(pa _val,int _l,int _r,int _x){val=_val;l=_l;r=_r;x=_x;}
};
struct cmp{
    bool operator()(data a,data b){return a.val<b.val;}
};
priority_queue<data,vector<data>,cmp>q;
inline void pushup(int p){
    int l=tr[p].ls,r=tr[p].rs;
    tr[p].x=tr[l].x>tr[r].x?tr[l].x:tr[r].x;
    tr[p].x.first+=tr[p].tag;
}
inline void add(int &p,int l,int r,int x,int y,int val){
    tr[++owo]=tr[p];p=owo;
    if(x<=l&&r<=y){tr[p].tag+=val;tr[p].x.first+=val;return;}
    int mid=l+r>>1;
    if(x<=mid) add(tr[p].ls,l,mid,x,y,val);
    if(y>mid) add(tr[p].rs,mid+1,r,x,y,val);pushup(p);
}
inline void ins(int &p,int l,int r,int x){
    tr[++owo]=tr[p];p=owo;if(l==r){tr[p].x=make_pair(0,l);return;}
    int mid=l+r>>1;
    if(x<=mid) ins(tr[p].ls,l,mid,x);
    else ins(tr[p].rs,mid+1,r,x);
    pushup(p);
}
inline pa ask(int p,int l,int r,int x,int y){
    if(!p) return make_pair(-inf,0);
    if(x<=l&&r<=y) return tr[p].x;
    int mid=l+r>>1;pa res(-inf,0);
    if(x<=mid) res=max(res,ask(tr[p].ls,l,mid,x,y));
    if(y>mid) res=max(res,ask(tr[p].rs,mid+1,r,x,y));
    res.first+=tr[p].tag;return res;
}
int main(){
//  freopen("a.in","r",stdin);
//  freopen("a.out","w",stdout);
    n=read();K=read();tr[0].x.first=-inf;--K;
    for(int i=1;i<=n;++i){
        int x=read();rt[i]=rt[i-1];ins(rt[i],1,n,i);
        add(rt[i],1,n,lst[x]+1,i,x);
        lst[x]=i;q.push(data(tr[rt[i]].x,1,i,i));
    }while(K--){
        int x=q.top().x,l=q.top().l,r=q.top().r,y=q.top().val.second;q.pop();
        if(l<y) q.push(data(ask(rt[x],1,n,l,y-1),l,y-1,x));
        if(r>y) q.push(data(ask(rt[x],1,n,y+1,r),y+1,r,x));
    }printf("%lld\n",q.top().val.first);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325737490&siteId=291194637