记录编号 363906 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [HZOI 2016]你猜是不是DP 最终得分 100
用户昵称 GravatarGo灬Fire 是否通过 通过
代码语言 C++ 运行时间 1.590 s
提交时间 2017-01-14 09:28:44 内存使用 23.66 MiB
显示代码纯文本
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define Inf 2e9
#define ex(x) ( (x&1) ? x+1 : x-1 )
const int maxn=90000;
struct Edge{
	int next,to,flow;
}e[maxn*20];
int len,head[maxn],cur[maxn];
int n,m,start,end,ansflow,deep[maxn];
void Insert(int x,int y,int flow){
	len++;e[len].to=y;e[len].next=head[x];
	head[x]=len;e[len].flow=flow;
}
void Add_edge(int x,int y,int flow){
	Insert(x,y,flow);Insert(y,x,0);
}
int cnt,id[maxn],a[maxn],tot;
struct Segment_Tree{
	int pos[maxn];
	#define lson rt<<1,l,mid
	#define rson rt<<1|1,mid+1,r
	void Build(int rt,int l,int r,int type){
		pos[rt]=++cnt;
		if(l==r){
			int valu;scanf("%d",&valu);
			if(type==0){
				id[l]=pos[rt];a[rt]=valu;
			}
			else {
				pos[rt]=id[l];a[rt]-=valu;
				tot+=valu;
				if(a[rt]>0)Add_edge(start,pos[rt],a[rt]),tot+=a[rt];
				else Add_edge(pos[rt],end,-a[rt]);
			}
			return;
		}
		int mid=(l+r)>>1;
		Build(lson,type);Build(rson,type);
		if(!type){
			Add_edge(pos[rt],pos[rt<<1],Inf);
			Add_edge(pos[rt],pos[rt<<1|1],Inf);
		}
		else {
			Add_edge(pos[rt<<1],pos[rt],Inf);
			Add_edge(pos[rt<<1|1],pos[rt],Inf);
		}
	}
	void add(int s,int t,int rt,int l,int r,int type){
		if(s<=l && t>=r){
			if(type==0)Add_edge(cnt,pos[rt],Inf);
			else Add_edge(pos[rt],cnt,Inf);
			return;
		}
		int mid=(l+r)>>1;
		if(s<=mid)add(s,t,lson,type);
		if(t>mid)add(s,t,rson,type);
	}
}Black,White;
int Head,Tail,q[maxn];
bool Bfs(){
	Head=Tail=0;q[Tail++]=start;
	memset(deep,-1,sizeof(deep));deep[start]=1;
	while(Head^Tail){
		int k=q[Head++];
		for(int i=head[k];i;i=e[i].next){
			int j=e[i].to;
			if(deep[j]<0 && e[i].flow>0){
				deep[j]=deep[k]+1;
				q[Tail++]=j;
			}
		}
	}
	//printf("%d ",deep[end]);
	if(deep[end]<0)return false;
	return true;
}
int Dfs(int x,int flow){
	if(x==end || !flow)return flow;
	int tot=0;
	for(int &i=cur[x];i && flow;i=e[i].next){
		int j=e[i].to;
		if(e[i].flow>0 && deep[j]==deep[x]+1){
			int dd=Dfs(j,min(e[i].flow,flow));
			e[i].flow-=dd;e[ex(i)].flow+=dd;
			flow-=dd;tot+=dd;
			if(!flow)break;
		}
	}
	return tot;
}
void Maxflow(){
	while(Bfs()){
		memcpy(cur,head,sizeof(head));
		ansflow+=Dfs(start,Inf);
	}
}
void Init();
int main(){
	freopen("nicai.in","r",stdin);freopen("nicai.out","w",stdout);
	Init();
	getchar();getchar();
	return 0;
}
void Init(){
	scanf("%d%d",&n,&m);
	start=maxn-10;end=start+1;
	Black.Build(1,1,n,0);
	White.Build(1,1,n,1);

	for(int i=1;i<=m;i++){
		int type,l,r,valu;scanf("%d%d%d%d",&type,&l,&r,&valu);
		cnt++;tot+=valu;
		if(type==1){
			Add_edge(start,cnt,valu);
			Black.add(l,r,1,1,n,0);
		}
		else {
			Add_edge(cnt,end,valu);
			White.add(l,r,1,1,n,1);
		}
	}
	Maxflow();
	printf("%d\n",tot-ansflow);
}