HDU 6611 K Subsequence

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
typedef int ll;
typedef std::pair<ll,int> pr;
int n,m,s,t;
const ll inf = 1e9;
const int maxn = 100010,maxm = 2000000;
namespace mcmf{
    struct T{ int to,nxt,v,f; } way[maxm << 1];;
    int h[maxn],num = 1;
    inline void link(int x,int y,int v,int f){
        way[++num]={y,h[x],v,f}; h[x]=num;
        way[++num]={x,h[y],0,-f}; h[y]=num;
    }
    ll d[maxn],dis[maxn]; int vis[maxn],fr[maxn];
	inline bool dijkstra(int s,int t){
		std::priority_queue<pr,std::vector<pr>,std::greater<pr>> q;
		std::fill(dis + s,dis + t + 1,inf);
		std::fill(vis + s,vis + t + 1,0);
		for(dis[s] = 0,q.push(pr(0,s));!q.empty();){
			pr t=q.top(); q.pop(); if(vis[t.second]) continue; vis[t.second] = 1;
			for(int i=h[t.second];i;i=way[i].nxt){
				const ll v = way[i].f + d[t.second] - d[way[i].to];
				if(way[i].v && dis[way[i].to] > dis[t.second] + v){
					dis[way[i].to] = dis[t.second] + v; fr[way[i].to] = i;
					q.push(pr(dis[way[i].to],way[i].to));
				}
			}
		}
		return dis[t] < inf;
	}
    inline ll dfs(int x){
    	if(d[x] < inf) return d[x]; ll&ans = d[x];
    	for(int i=h[x];i;i=way[i].nxt) if(!way[i].v)
    		ans = std::min(ans,dfs(way[i].to) - way[i].f);
		return ans;
	}
    inline std::pair<ll,ll> ek(int s,int t,int cnt){
        ll flow = 0,cost = 0;
        std::fill(d + s,d + t + 1,inf); d[s] = 0;
        for(int i = s + 1;i<=t;++i) d[i] = dfs(i);
        while(dijkstra(s,t) && cnt--){
            ll sum = 0,fl = inf;
            for(int i=fr[t];i;i=fr[way[i^1].to])
                fl = std::min<ll>(way[i].v,fl), sum += way[i].f;
            flow += fl,cost += fl * sum;
            for(int i=fr[t];i;i=fr[way[i^1].to]) way[i].v -= fl,way[i ^ 1].v += fl;
            for(int i=s;i<=t;++i) d[i] += dis[i];
        }
        std::fill(h + s,h + t + 1,0); num = 1;
        return {flow,cost};
    }
}
int a[maxn];
const int sz = 100001;
int tr[sz],tot;
inline void add(int pos,int v){
	while(pos){
		int x = ++tot;
		if(tr[pos]) mcmf::link(x,tr[pos],inf,0);
		mcmf::link(x,v,inf,0); tr[pos] = x;
		pos &= pos - 1;
	}
}
inline void qry(int pos,int v){
	for(;pos<sz;pos+=pos&-pos)
		if(tr[pos]) mcmf::link(v,tr[pos],1,0);
}
int main(){
    std::ios::sync_with_stdio(false),std::cin.tie(0); int t;
    for(std::cin >> t;t--;){
    	int n,k;
    	std::cin >> n >> k; tot = n << 1;
    	for(int i=1;i<=n;++i) {
			std::cin >> a[i];
			mcmf::link(0,i,1,0), mcmf::link(i,i+n,1,-a[i]);
		}
    	std::fill(tr,tr + sz,0);
    	for(int i=n;i>=1;--i) qry(a[i],i + n),add(a[i],i);
    	// for(int i=1;i<=n;++i) for(int j=i + 1;j<=n;++j) if(a[i] <= a[j])
    	//		mcmf::link(i + n,j,1,0);
		++tot;
		for(int i=1;i<=n;++i) mcmf::link(i + n,tot,1,0);
		auto ans = mcmf::ek(0,tot,k);
		std::cout << - ans.second << '
';
	}
}

原文地址:https://www.cnblogs.com/skip1978/p/11454925.html