zoukankan      html  css  js  c++  java
  • BZOJ 3218(a + b Problem-二分图套值域线段树)




    出这题的人是怎么想出来的……

    言归正传,这题是二分图套值域线段树。

    首先经过 @Vfleaking的神奇建图后,把图拆成二分图,

    不妨利用有向图最小割的性质建图(以前我一直以为最小割和边的方向无关,可这样的话很奇怪哦……)

    理解悲剧……

    我们可以利用边有向的性质解决黑白色块……

    然后发现线段树很多……主席树闪亮登场

    然后·就这麽A了?…………

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    #include<cmath>
    #include<cctype>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define MEM(a) memset(a,0,sizeof(a))
    #define MEMI(a) memset(a,127,sizeof(a))
    #define MEMi(a) memset(a,128,sizeof(a))
    #define INF (2139062143)
    #define MAXN (500000 +10)
    #define MAXM (500000 +10)
    int n,m,s,t;
    int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},weight[MAXM],size=1;
    void addedge(int u,int v,int w)
    {
    	edge[++size]=v;
    	weight[size]=w;
    	next[size]=pre[u];
    	pre[u]=size;
    }
    void addedge2(int u,int v,int w){/*cout<<u<<' '<<v<<' '<<w<<endl;*/addedge(u,v,w),addedge(v,u,0);}
    int cnt[MAXN]={0},d[MAXN]={0};
    long long totflow=0;
    long long sap(int x,int flow)
    {
    	if (x==t) return flow;
    	int nowflow=0;
    	Forp(x)
    	{
    		int &v=edge[p];
    		if (d[v]==d[x]-1&&weight[p])
    		{
    			long long fl=sap(v,min(weight[p],flow));
    			weight[p]-=fl,weight[p^1]+=fl,nowflow+=fl,flow-=fl;
    			if (!flow) return nowflow;
    		}
    	}	
    	if (!(--cnt[d[x]++])) d[s]=t+1;
    	cnt[d[x]]++;
    	return nowflow;
    }
    struct node
    {
    	node *ch[2];
    	node(){ch[0]=ch[1]=NULL;}
    }q[MAXN],*root[MAXN]={NULL};
    int tail=0;
    void ins(node *&p,node *x,int l,int r,int c)
    {
    	int m=(l+r) >>1;
    	p=&q[++tail];
    	if (x) *p=*x;
    	if (l==r) return;
    	if (c<=m) ins(p->ch[0],p->ch[0],l,m,c);
    	else ins(p->ch[1],p->ch[1],m+1,r,c);		
    }
    void print(node *p)
    {
    	//cout<<
    }
    node *ans[MAXN];
    int ans_siz=0;
    void qur(node *p,int l,int r,int L,int R)
    {
    	if (!p||L>R) return;
    	int m=l+r >>1;
    	if (L<=l&&r<=R) {ans[++ans_siz]=p;return;}
    	if (l==r) return;
    	if (L<=m) qur(p->ch[0],l,m,L,R);
    	if (m<R) qur(p->ch[1],m+1,r,L,R);
    }
    int a2[MAXN],a[MAXN],b[MAXN],w[MAXN],l[MAXN],r[MAXN],p[MAXN];
    int main()
    {
    	freopen("bzoj3218.in","r",stdin);
    //	freopen(".out","w",stdout);
    	scanf("%d",&n);
    	For(i,n) scanf("%d%d%d%d%d%d",&a[i],&b[i],&w[i],&l[i],&r[i],&p[i]);
    	memcpy(a2,a,sizeof(a));
    	sort(a2+1,a2+n+1);
    	int size=unique(a2+1,a2+n+1)-(a2+1);
    	For(i,n) 
    	{
    		a[i]=lower_bound(a2+1,a2+size+1,a[i])-(a2);
    		l[i]=lower_bound(a2+1,a2+size+1,l[i])-(a2);
    		r[i]=upper_bound(a2+1,a2+size+1,r[i])-(a2)-1;
    	}
    	For(i,n) ins(root[i],root[i-1],1,size,a[i]);
    	
    	s=2*n+1; t=2*n+2;
    	For(i,n) addedge2(s,i,b[i]),addedge2(i,t,w[i]),addedge2(i,n+i,p[i]);
    	For(i,tail)
    	{
    		if (q[i].ch[0]) addedge2(t+i,t+((q[i].ch[0])-q),INF);
    		if (q[i].ch[1]) addedge2(t+i,t+((q[i].ch[1])-q),INF);
    	}
    	For(i,n)
    	{
    		ans_siz=0;
    		qur(root[i],1,size,a[i],a[i]);
    		qur(root[i-1],1,size,a[i],a[i]);
    		node *cur=ans[1],*last=NULL;
    		if (ans_siz>1) last=ans[2];
    		//cout<<t+((cur)-(q))<<'*';
    		addedge2(t+((cur)-(q)),i,INF);
    		
    		if (ans_siz>1) addedge2(t+(cur-(q)),t+((last)-(q)),INF);
    	}
    	For(i,n)
    	{
    		ans_siz=0;
    		qur(root[i],1,size,l[i],r[i]);
    		For(j,ans_siz) addedge2(n+i,t+((ans[j])-(q)),INF);
    	}	
    	//cout<<2*n+2+tail<<endl;	
    	cnt[0]=2*n+2+tail;
    	while (d[s]<=t) {totflow+=sap(s,INF);} 
    	//For(i,2*n+tail) cout<<d[i]<<' ';
    	long long ans=-totflow;
    	For(i,n) ans+=b[i]+w[i];
    	cout/*<<totflow<<' '*/<<ans<<endl;	
    	
    	return 0;
    }






  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3144807.html
Copyright © 2011-2022 走看看