思路跟 happiness 差不多,只不过需要用主席树优化一下建图。
#include<bits/stdc++.h>
#define N 5010
#define INF 0x7fffffff
using namespace std;
int read()
{
int x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x;
}
struct data
{
int a,b,w,l,r,p;
}a[N];
struct Tree
{
int lc,rc;
}t[100010];
int n,sum,S,T;
int tot,b[N*3];
int node,root[N];
int cnt=1,head[200010],cur[200010],to[2000010],nxt[2000010],c[2000010];
int num[200010];
queue<int>q;
void adde(int u,int v,int ci)
{
to[++cnt]=v;
c[cnt]=ci;
nxt[cnt]=head[u];
head[u]=cnt;
to[++cnt]=u;
c[cnt]=0;
nxt[cnt]=head[v];
head[v]=cnt;
}
void build(int &u,int l,int r)
{
u=++node;
if(l==r) return;
int mid=(l+r)>>1;
build(t[u].lc,l,mid);
build(t[u].rc,mid+1,r);
adde(T+u,T+t[u].lc,INF);
adde(T+u,T+t[u].rc,INF);
}
void update(int last,int &u,int l,int r,int x,int id)
{
u=++node;
adde(T+u,1+id,INF);
if(l==r)
{
if(last) adde(T+u,T+last,INF);
return;
}
int mid=(l+r)>>1;
t[u]=t[last];
if(x<=mid) update(t[last].lc,t[u].lc,l,mid,x,id);
else update(t[last].rc,t[u].rc,mid+1,r,x,id);
if(t[u].lc) adde(T+u,T+t[u].lc,INF);
if(t[u].rc) adde(T+u,T+t[u].rc,INF);
}
void query(int u,int l,int r,int ql,int qr,int newnode)
{
if(!u) return;
if(ql<=l&&r<=qr)
{
adde(newnode,T+u,INF);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) query(t[u].lc,l,mid,ql,qr,newnode);
if(qr>mid) query(t[u].rc,mid+1,r,ql,qr,newnode);
}
bool bfs()
{
memset(num,-1,sizeof(num));
memcpy(cur,head,sizeof(cur));
num[S]=0;
q.push(S);
while(!q.empty())
{
int u=q.front();
q.pop();
for(register int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(c[i]&&num[v]==-1)
{
num[v]=num[u]+1;
q.push(v);
}
}
}
return num[T]!=-1;
}
int dfs(int u,int minflow)
{
if(!minflow||u==T) return minflow;
int preflow=0,nowflow;
for(register int i=cur[u];i;i=nxt[i])
{
cur[u]=i;
int v=to[i];
if(num[v]==num[u]+1&&(nowflow=dfs(v,min(minflow-preflow,c[i]))))
{
preflow+=nowflow;
c[i]-=nowflow;
c[i^1]+=nowflow;
if(!(minflow-preflow)) break;
}
}
return preflow;
}
int dinic()
{
int maxflow=0;
while(bfs())
maxflow+=dfs(S,INF);
return maxflow;
}
int main()
{
n=read();
S=1,T=1+n+1;
for(register int i=1;i<=n;i++)
{
a[i].a=read(),a[i].b=read(),a[i].w=read(),a[i].l=read(),a[i].r=read(),a[i].p=read();
b[++tot]=a[i].l,b[++tot]=a[i].r,b[++tot]=a[i].a;
sum+=a[i].b+a[i].w;
adde(S,1+i,a[i].b);
adde(1+i,T,a[i].w);
}
sort(b+1,b+tot+1);
int nn=unique(b+1,b+tot+1)-b-1;
for(register int i=1;i<=n;i++)
{
a[i].a=lower_bound(b+1,b+nn+1,a[i].a)-b;
a[i].l=lower_bound(b+1,b+nn+1,a[i].l)-b;
a[i].r=lower_bound(b+1,b+nn+1,a[i].r)-b;
}
// build(root[0],1,nn);
for(register int i=1;i<=n;i++)
{
update(root[i-1],root[i],1,nn,a[i].a,i);
++node,adde(1+i,T+node,a[i].p);
query(root[i-1],1,nn,a[i].l,a[i].r,T+node);
}
printf("%d
",sum-dinic());
return 0;
}
/*
10
0 1 7 3 9 2
7 4 0 9 10 5
1 0 4 2 10 2
7 9 1 5 7 2
6 3 5 3 6 2
6 6 4 1 8 1
6 1 6 0 6 5
2 2 5 0 9 3
5 1 3 0 2 5
5 6 7 1 1 2
*/
/*
2
2 2 100 1 3 25
2 100 2 1 3 25
*/