题解 [REOI-p1] 回忆

传送门

哭死。
“每条边只能被覆盖一次”的条件都写脸上了还不知道是网络流。

知道是网络流了就按题意连边即可
需要线段树优化建图

复杂度 \(O(能过)\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define fir first
#define sec second
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m1, m2;
bool vis[N];
#define tl(p) tl[p]
#define tr(p) tr[p]
pair<int, int> a[N], b[N];
int dis[N], back[N], inc[N];
int tl[N<<2], tr[N<<2], id1[N<<2], id2[N<<2], pos[N], val1[N], val2[N];
int head[N], uni[N], sid[N], eid[N], usiz, ecnt=1, sup_s, s, t, tot, ans1, ans2;
struct edge{int to, next, flw, cst;}e[N<<1];
inline void add(int s, int t, int f, int c) {e[++ecnt]={t, head[s], f, c}; head[s]=ecnt;}

void build(int p, int l, int r) {
	tl(p)=l; tr(p)=r;
	if (tl(p)==tr(p)) {pos[l]=id1[p]=id2[p]=++tot; return ;}
	int mid=(l+r)>>1;
	build(p<<1, l, mid);
	build(p<<1|1, mid+1, r);
	id1[p]=++tot, id2[p]=++tot;
	add(id1[p], id1[p<<1], INF, 0), add(id1[p<<1], id1[p], 0, 0);
	add(id1[p], id1[p<<1|1], INF, 0), add(id1[p<<1|1], id1[p], 0, 0);
	add(id2[p<<1], id2[p], INF, 0), add(id2[p], id2[p<<1], 0, 0);
	add(id2[p<<1|1], id2[p], INF, 0), add(id2[p], id2[p<<1|1], 0, 0);
}
void upd1(int p, int l, int r, int s) {
	if (l<=tl(p)&&r>=tr(p)) {
		add(s, id1[p], INF, 0), add(id1[p], s, 0, 0);
		return ;
	}
	int mid=(tl(p)+tr(p))>>1;
	if (l<=mid) upd1(p<<1, l, r, s);
	if (r>mid) upd1(p<<1|1, l, r, s);
}
void upd2(int p, int l, int r, int t) {
	if (l<=tl(p)&&r>=tr(p)) {
		add(id2[p], t, INF, 0), add(t, id2[p], 0, 0);
		return ;
	}
	int mid=(tl(p)+tr(p))>>1;
	if (l<=mid) upd2(p<<1, l, r, t);
	if (r>mid) upd2(p<<1|1, l, r, t);
}

bool spfa(int s, int t) {
	queue<int> q;
	for (int i=1; i<=tot; ++i) dis[i]=INF, back[i]=-1;
	dis[s]=0; inc[s]=INF;
	q.push(s);
	while (q.size()) {
		int u=q.front(); q.pop();
		vis[u]=0;
		for (int i=head[u],v; ~i; i=e[i].next) {
			v = e[i].to;
			if (e[i].flw && dis[v]>dis[u]+e[i].cst) {
				dis[v]=dis[u]+e[i].cst;
				back[v]=i; inc[v]=min(inc[u], e[i].flw);
				if (!vis[v]) q.push(v), vis[v]=1;
			}
		}
	}
	return ~back[t];
}

signed main()
{
	n=read(); m1=read(); m2=read();
	memset(head, -1, sizeof(head));
	for (int i=1; i<=m1; ++i) {
		uni[++usiz]=a[i].fir=read();
		uni[++usiz]=a[i].sec=read();
	}
	for (int i=1; i<=m2; ++i) {
		uni[++usiz]=b[i].fir=read();
		uni[++usiz]=b[i].sec=read();
	}
	for (int i=1; i<=m1; ++i) val1[i]=read();
	for (int i=1; i<=m2; ++i) val2[i]=read();
	sort(uni+1, uni+usiz+1);
	usiz=unique(uni+1, uni+usiz+1)-uni-1;
	for (int i=1; i<=m1; ++i) {
		a[i].fir=lower_bound(uni+1, uni+usiz+1, a[i].fir)-uni;
		a[i].sec=lower_bound(uni+1, uni+usiz+1, a[i].sec)-uni;
	}
	for (int i=1; i<=m2; ++i) {
		b[i].fir=lower_bound(uni+1, uni+usiz+1, b[i].fir)-uni;
		b[i].sec=lower_bound(uni+1, uni+usiz+1, b[i].sec)-uni;
	}
	sup_s=++tot; s=++tot; t=++tot;
	add(sup_s, s, n, 0), add(s, sup_s, 0, 0);
	for (int i=1; i<=m1; ++i) {
		sid[i]=++tot;
		add(s, sid[i], 1, -val1[i]), add(sid[i], s, 0, val1[i]);
	}
	for (int i=1; i<=m2; ++i) {
		eid[i]=++tot;
		add(eid[i], t, 1, -val2[i]), add(t, eid[i], 0, val2[i]);
	}
	build(1, 1, usiz);
	for (int i=2; i<=usiz; ++i) {
		add(pos[i-1], pos[i], 1, uni[i-1]-uni[i]);
		add(pos[i], pos[i-1], 0, uni[i]-uni[i-1]);
	}
	for (int i=1; i<=m1; ++i) {
		upd1(1, a[i].fir, a[i].sec, sid[i]);
		// for (int j=a[i].fir; j<=a[i].sec; ++j)
		// 	add(sid[i], pos[j], INF, 0), add(pos[j], sid[i], 0, 0);
	}
	for (int i=1; i<=m2; ++i) {
		upd2(1, b[i].fir, b[i].sec, eid[i]);
		// for (int j=b[i].fir; j<=b[i].sec; ++j)
		// 	add(pos[j], eid[i], INF, 0), add(eid[i], pos[j], 0, 0);
	}
	while (spfa(sup_s, t)) {
		ans1+=inc[t]; ans2+=dis[t]*inc[t];
		for (int u=t; u!=sup_s; u=e[back[u]^1].to) {
			e[back[u]].flw-=inc[t];
			e[back[u]^1].flw+=inc[t];
		}
	}
	// cout<<"ans1: "<<ans1<<endl;
	printf("%lld\n", ans1==n?-ans2:-1ll);

	return 0;
}
posted @ 2022-08-01 21:10  Administrator-09  阅读(2)  评论(0编辑  收藏  举报