首页 > 其他分享 >CF547D Mike and Fish 小丑做法--zhengjun

CF547D Mike and Fish 小丑做法--zhengjun

时间:2023-07-28 18:12:31浏览次数:36  
标签:Mike return -- Fish ++ int bool col ta

写到一半发现标签有二分图就不对劲了,题解区里都是欧拉回路。

然而我是随机化+模拟网络流!自豪

首先可以先建模,观察同一种颜色,发现每一行或每一列的限制即为 \(\lfloor\frac{t}{2}\rfloor\le x\le \lceil\frac{t}{2}\rceil\)。

然后套路地把横坐标和纵坐标分开来建个二分图,建立源点汇点之后连边,发现是个有源汇上下界可行流。

转化为无源汇的可行流之后,考虑模拟网络流。

类似匈牙利算法的那样不断找增广路即可。

但是,发现这样需要增广 \(O(n)\) 次,感觉可能跑步过去。

所以考虑随机化,先随机一个顺序,按顺序加点,直到该点对应的行或列的限制达到了下界。

然后就这么跑过去了……

代码

#include<bits/stdc++.h>
#define Assert(...) if(!(__VA_ARGS__))\
	fprintf(stderr,"assert fail: %s",#__VA_ARGS__),exit(0)
using namespace std;
using ll=long long;
const int N=2e5+10,m=2e5;
int n;
struct node{
	int x,y;
}a[N];
int cur[N];
mt19937 rnd(time(0));
int ta[N],tb[N],cnta[N],cntb[N];
bool chka(int x){
	return ta[x]<=(cnta[x]-1)/2;
}
bool chkb(int y){
	return tb[y]<=(cntb[y]-1)/2;
}
bool Chka(int x){
	return ta[x]*2+1<cnta[x];
}
bool Chkb(int y){
	return tb[y]*2+1<cntb[y];
}
int col[N];
set<int>H[2][N],L[2][N];
void rev1(int i){
	if(!col[i])H[col[i]][a[i].x].erase(i);
	else L[col[i]][a[i].y].erase(i);
	col[i]^=1;
	if(!col[i])H[col[i]][a[i].x].insert(i);
	else L[col[i]][a[i].y].insert(i);
}
void rev2(int i){
	if(col[i])H[col[i]][a[i].x].erase(i);
	else L[col[i]][a[i].y].erase(i);
	col[i]^=1;
	if(col[i])H[col[i]][a[i].x].insert(i);
	else L[col[i]][a[i].y].insert(i);
}
bool find1(int);
bool find2(int);
bool find3(int);
bool find4(int);
int t1,t2,s1[N],s2[N],vis1[N],vis2[N];
bool find1(int h){
	if(vis1[h])return 0;
	s1[++t1]=h,vis1[h]=1;
	if(cnta[h]==ta[h]*2-1)return ta[h]--,1;
	for(int i:H[0][h]){
		if(find2(a[i].y))return rev1(i),1;
	}
	return 0;
}
bool find2(int l){
	if(vis2[l])return 0;
	s2[++t2]=l,vis2[l]=1;
	if(chkb(l))return tb[l]++,1;
	for(int i:L[1][l]){
		if(find1(a[i].x))return rev1(i),1;
	}
	return 0;
}
bool find3(int h){
	if(vis1[h])return 0;
	s1[++t1]=h,vis1[h]=1;
	if(chka(h))return ta[h]++,1;
	for(int i:H[1][h]){
		if(find4(a[i].y))return rev2(i),1;
	}
	return 0;
}
bool find4(int l){
	if(vis2[l])return 0;
	s2[++t2]=l,vis2[l]=1;
	if(cntb[l]==tb[l]*2-1)return tb[l]--,1;
	for(int i:L[0][l]){
		if(find3(a[i].x))return rev2(i),1;
	}
	return 0;
}
int main(){
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].x,&a[i].y);
		cnta[a[i].x]++,cntb[a[i].y]++;
	}
	iota(cur,cur+1+n,0),shuffle(cur+1,cur+1+n,rnd);
	for(int x=1;x<=n;x++){
		int i=cur[x];
		if(Chka(a[i].x)&&Chkb(a[i].y)){
			col[i]=1,ta[a[i].x]++,tb[a[i].y]++;
		}
	}
	for(int i=1;i<=n;i++){
		if(!col[i])H[col[i]][a[i].x].insert(i);
		else L[col[i]][a[i].y].insert(i);
	}
	for(int i=1;i<=m;i++){
		for(;Chka(i);){
			Assert(find1(i));
			ta[i]++;
			for(;t1;)vis1[s1[t1--]]=0;
			for(;t2;)vis2[s2[t2--]]=0;
		}
	}
	for(int i=1;i<=n;i++){
		if(col[i])H[col[i]][a[i].x].insert(i);
		else L[col[i]][a[i].y].insert(i);
	}
	for(int i=1;i<=m;i++){
		for(;Chkb(i);){
			Assert(find4(i));
			tb[i]++;
			for(;t1;)vis1[s1[t1--]]=0;
			for(;t2;)vis2[s2[t2--]]=0;
		}
	}
	for(int i=1;i<=n;i++)putchar("br"[col[i]]);
	cerr<<1.0*clock()/CLOCKS_PER_SEC<<"s\n";
	return 0;
}

标签:Mike,return,--,Fish,++,int,bool,col,ta
From: https://www.cnblogs.com/A-zjzj/p/17588579.html

相关文章

  • Microsoft Speech SDK 5.1 微软的文字转语音TTS
    下载安装 SpeechSDK5.11. WindowsSpeechSDK5.1版本支持xp系统和server2003系统,需要下载安装。XP系统默认只带了个MicrosoftSam英文男声语音库,想要中文引擎就需要安装WindowsSpeechSDK5.1。下载地址:http://www.microsoft.com/download/en/details.aspx?id=101212.Wi......
  • # 实验15
    实验15题目安装一个新的int9中断例程,在DOS下,按下’A’键后,除非不再松开,如果松开,就会显示满屏幕的’A’,其他键的功能照常。代码:assumecs:codecodesegmentstart:pushcspopdsmovax,0moves,axmovsi,offsetint9movdi,204hmovcx,offsetint9end-offsetint9......
  • lazy 线段树代码
    描述 代码:1classNode{2intl,r;3intsum;4intlazy;5}67classSegmentTree{89privateNode[]tree;1011privateint[]nums;1213publicSegmentTree(int[]nums){14intn=nums.length;15......
  • CF1851 A-G
    linkA非常简单的比较大小问题#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<stack>#include<set>#include<map>#include<ctime>#include&l......
  • CTFer成长记录——CTF之Misc专题·攻防世界—适合作为桌面
    一、题目链接https://adworld.xctf.org.cn/challenges/list二、解法步骤  附件是一张炫酷的.png图片:  常规操作无效后,考虑其他的隐写软件:stegsovle。打开后,尝试不同的文件通道,发现有二维码出现:扫描后是一段16进制字符串:  在010中新建16进制文件,使用ctrl+shitf+v......
  • 七日杀,客户端mod添加
    打开七日杀根目录   #添加一个文件夹"Mods“,并且将mod文件包解压进去打开七日杀属性,设置版本   #最后一步,取消反作弊运行游戏  #点击Run&Saveasdefault开始游戏 #在好友界面加入游戏 ......
  • lea指令调用
    lea指令(LoadEffectiveAddress)在x86汇编语言中的作用是将一个有效地址(即一个内存地址或寄存器地址的偏移量)加载到目标寄存器中,而不是加载一个实际的内存值。lea指令的使用场景通常有以下几种:计算数组元素的地址:假设有一个数组arr,每个元素大小为4个字节,要获取第i个元素的地址,......
  • idea远程连接服务器代码,进行debug操作
    1.配置远程断点 2.将你的springboot项目上传至远程服务器3.在你的远程服务器通过下面的命令启动你的项目nohupjava-Xdebug-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005-jarmonitor_26-0.0.1-SNAPSHOT.jar--server.port=8000>nohup.log......
  • TSINGSEE青犀视频汇聚融合平台EasyCVR的中性化版本如何配置?
    TSINGSEE青犀视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等,平台融合性强、开放度高、部署轻快,在智慧工地、智慧园区、智慧工厂、智慧码头、智慧水利等场景中有着广泛的应......
  • CTFer成长记录——CTF之Misc专题·攻防世界—斑马斑马
    一、题目链接  https://adworld.xctf.org.cn/challenges/list二、解法步骤  下载附件,发现是一张斑马:  常规的隐写解密操作都无效,考虑特点:斑马——>黑白条纹——>条形码。在线识别条形码网站:https://products.aspose.app/barcode/zh-hans/recognize#  解码得到:FLAGIS......