s to each cow edge, capacity 1
Each sunscreen to the T-Edge, volume cover
Each cow to SPF in its own range of sunscreen edge, capacity inf
Optimize the graph with the line segment tree to run the maximum flow.
#include <cstdio>const int n=7010,inf=~0u>>2;struct edge{int T,f;edge*nxt,*pair;} *g[n],*d[n],pool[60000],*cur=pool,*p;int N,m,tot,root,id[n],l[n],r[n],spf[n][2],i,x,y,s,t,h[n],gap[n],maxflow; inline int min (int x,int y) {return x<y?x:y;} inline void Add (int s,int t,int f) {p=cur++;p->t=t;p->f=f;p->nxt=g[s];g[s]=p; p=cur++;p->t=s;p->f=0;p->nxt=g[t];g[t]=p; G[s]->pair=g[t];g[t]->pair=g[s];} int sap (int v,int flow) {if (v==t) return flow; int rec=0; For (Edge *p=d[v];p; p=p->nxt) if (h[v]==h[p->t]+1&&p->f) {int Ret=sap (p->t,min (flow-rec,p->f) ); p->f-=ret;p->pair->f+=ret;d[v]=p; if ((Rec+=ret) ==flow) return flow; } if (! ( --GAP[H[V]]) h[s]=t; gap[++h[v]]++;d [V]=g[v]; Return rec;} int build (int a,int b) {int x=++tot; if (a==b) return id[a]=x; int mid= (A+B) >>1; Add (X,l[x]=build (A,mid), INF), Add (X,r[x]=build (mid+1,b), INF); return x;} void Ask (int x,int a,int b,int c,int d,int p) {if (C<=a&&b<=d) {add(p,x,inf); return;} int mid= (A+B) >>1; if (C<=mid) ask (l[x],a,mid,c,d,p); if (D>mid) ask (r[x],mid+1,b,c,d,p);} int main () {scanf ("%d%d", &n,&m); tot=n+m; Root=build (1,1000); s=tot+1,t=s+1; for (i=1;i<=n;i++) scanf ("%d%d", &spf[i][0],&spf[i][1]), add (s,i,1); for (i=1;i<=m;i++) scanf ("%d%d", &x,&y), add (Id[x],i+n,inf), add (i+n,t,y); for (i=1;i<=n;i++) ask (Root,1,1000,spf[i][0],spf[i][1],i); for (gap[0]=t,i=1;i<=t;i++) d[i]=g[i]; while (h[s]<t) Maxflow+=sap (S,inf); Return printf ("%d", Maxflow), 0;}
BZOJ1707: [Usaco2007 nov]tanning Distributing sunscreen