2018.09.27 codeforces1045A. Last chance(线段树优化建图+最大流)

时间:2022-09-28 11:47:01

传送门

看完题应该都知道是网络流了吧。

但是第二种武器直接建图会gg。

因此我们用线段树优化建图。

具体操作就是,对于这m个人先建一棵线段树,父亲向儿子连容量为inf的边,最后叶子结点向对应的人连容量为1的边。

这样给第二种武器对应连边的时候直接给区间连边就行了。

对于操作三,我们直接贪心流掉两个人,剩下的一个人不流就行了。

代码:

#include<bits/stdc++.h>
#define N 200005
#define inf 0x3f3f3f3f
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
bool vis[N];
int n,m,id[N],q[N],hd,tl,tot,Begin,ans,d[N],first[N],cnt,s,t;
struct edge{int v,c,next;};
map<int,int>mp[N];
edge e[N];
inline void add(int u,int v,int c){
	e[++cnt].v=v,e[cnt].c=c,e[cnt].next=first[u],first[u]=cnt;
	e[++cnt].v=u,e[cnt].c=0,e[cnt].next=first[v],first[v]=cnt;
}
inline bool bfs(){
	queue<int>q;
	q.push(s);
	memset(d,-1,sizeof(d));
	d[s]=0;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=first[x];i!=-1;i=e[i].next){
			int v=e[i].v;
			if(e[i].c<=0||d[v]!=-1)continue;
			d[v]=d[x]+1;
			if(v==t)return true;
			q.push(v);
		}
	}
	return false;
}
inline int dfs(int x,int f){
	if(!f||x==t)return f;
	int flow=f;
	for(int i=first[x];i!=-1;i=e[i].next){
		int v=e[i].v;
		if(flow&&e[i].c>0&&d[v]==d[x]+1){
			int tmp=dfs(v,min(flow,e[i].c));
			if(tmp==0)d[v]=-1;
			flow-=tmp;
			e[i].c-=tmp;
			e[i^1].c+=tmp;
		}
	}
	return f-flow;
}
inline void solve(){while(bfs())ans+=dfs(s,inf);}
inline void build(int p,int l,int r){
	id[p]=++tot;
	if(l==r){add(id[p],l,1);return;}
	build(lc,l,mid),build(rc,mid+1,r);
	add(id[p],id[lc],inf),add(id[p],id[rc],inf);
}
inline void update(int p,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr){add(tot,id[p],1);return;}
	if(qr<=mid)update(lc,l,mid,ql,qr);
	else if(ql>mid)update(rc,mid+1,r,ql,qr);
	else update(lc,l,mid,ql,mid),update(rc,mid+1,r,mid+1,qr);
}
int tmp=0;
inline void query(int p){
	if(p>=Begin){tmp=p-Begin+1;return;}
	map<int,int>::iterator it=mp[p].begin();
	query(it->first);
	--it->second;
	if(!it->second)mp[p].erase(it);
}
int main(){
	memset(first,-1,sizeof(first)),n=read(),tot=m=read(),cnt=-1,s=++tot,build(1,1,m),Begin=tot+1;
	for(int i=1;i<=n;++i){
		int op=read();
		++tot;
		if(op==0){
			int k=read();
			while(k--){
				int x=read();
				add(tot,x,1);
			}
			add(s,tot,1);
		}
		else if(op==1){
			int ql=read(),qr=read();
			update(1,1,m,ql,qr),add(s,tot,1);
		}
		else{
			int a=read(),b=read(),c=read();
			vis[a]=vis[b]=1,ans+=2;
			add(tot,a,0),e[cnt].c=1,add(tot,b,0),e[cnt].c=1,add(tot,c,1);
		}
	}
	t=++tot;
	for(int i=1;i<=m;++i)if(!vis[i])add(i,t,1);
	solve();
	printf("%d\n",ans);
	for(int i=1;i<=tot;++i)for(int j=first[i];j;j=e[j].next)if((j&1)&&e[j].c)mp[i][e[j].v]=e[j].c;
	for(int i=1;i<=m;++i){
		bool f=true;
		for(int j=first[i];j&&f;j=e[j].next)if(e[j].v==t&&e[j].c)f=false;
		if(f)query(i),printf("%d %d\n",tmp,i);
	}
	return 0;
}

2018.09.27 codeforces1045A. Last chance(线段树优化建图+最大流)的更多相关文章

  1. 【BZOJ4276】&lbrack;ONTAK2015&rsqb;Bajtman i Okr&aogon;g&lstrok;y Robin 线段树优化建图&plus;费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  2. BZOJ5017 &lbrack;SNOI2017&rsqb;炸弹 - 线段树优化建图&plus;Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  3. 【BZOJ3681】Arietta 树链剖分&plus;可持久化线段树优化建图&plus;网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  4. 【ARC069F】Flags 2-sat&plus;线段树优化建图&plus;二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  5. 【bzoj5017】&lbrack;Snoi2017&rsqb;炸弹 线段树优化建图&plus;Tarjan&plus;拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  6. 【bzoj4699】树上的最短路(树剖&plus;线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  7. 【bzoj3073】&lbrack;Pa2011&rsqb;Journeys 线段树优化建图&plus;堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  8. 【bzoj4383】&lbrack;POI2015&rsqb;Pustynia 线段树优化建图&plus;差分约束系统&plus;拓扑排序

    题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...

  9. BZOJ&lowbar;4276&lowbar;&lbrack;ONTAK2015&rsqb;Bajtman i Okr&aogon;g&lstrok;y Robin&lowbar;线段树优化建图&plus;最大费用最大流

    BZOJ_4276_[ONTAK2015]Bajtman i Okrągły Robin_线段树优化建图+最大费用最大流 Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1 ...

随机推荐

  1. &lbrack;SPI&amp&semi;I2C&rsqb;I2C和SPI协议介绍

    IIC vs SPI 现今,在低端数字通信应用领域,我们随处可见IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身 ...

  2. iOS全局调用的提示 没有网络 没有更多 等。。 短时间内自动消失

    本来想用SVProgressHUD 但是由于这个需求相对要简单 所以自己写了 下面上代码 .h 文件 #import <UIKit/UIKit.h> @interface HaveNoMo ...

  3. 二模 (12)day2

    第一题: 题目大意: 有N颗糖,两个人轮流取,每次只能取质数颗,不能取的输.求先取者若必胜,最少需要多少步胜利.(N<=10000) 解题过程: 1.看到N的范围比较小,先打个素数表,然后dp即 ...

  4. (转)linux多线程,线程的分离与结合

    转自:http://www.cnblogs.com/mydomain/archive/2011/08/14/2138454.htm 线程的分离与结合     在任何一个时间点上,线程是可结合的(joi ...

  5. FZU-1925&plus;几何

    题意简单. 由于没有注意到椭圆不一定是在圆心..贡献无数的wa..... #include<stdio.h> #include<string.h> #include<al ...

  6. vue指令v-once示例解析

    只渲染元素和组件一次.随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过.这可以用于优化更新性能. <!-- 单个元素 --> <span v-once>This ...

  7. docker images

    docker images 介绍 镜像是动态的容器的静态表示,包括容器所要运行的应用代码以及运行时的配置.Docker镜像包括一个或者多个只读层(read-only layers),因此,镜像一旦被创 ...

  8. &lbrack;译&rsqb;在vuejs中使用任意js库

    原文 全局变量 最naive的办法是通过附加类库到window对象,使之成为全局变量: entry.js window._ = require('lodash'); MyComponent.vue e ...

  9. 查出了a表,然后对a表进行自查询,a表的别名t1,t2如同两张表,因为t1,t2查询的条件不一样,真的如同两张表,关联两张表,可以将两行或者多行数据合并成一行,不必使用wm&lowbar;concat&lpar;&rpar;函数。为了将t2表的数据全部查出来使用了右连接。

    with a as( select nsr.zgswj_dm, count(distinct nsr.djxh) cnt, 1 z from hx_fp.fp_ly fp, hx_dj.dj_nsrx ...

  10. Centos6&period;8 安装dlib库时出错【升级gcc 到4&period;9&period;0以上】

    在centos6.8上安装dlib库时出现错误: 1.CMake must be installed to build the following extensions: dlib 没有安装CMake ...