CF1361C. Johnny and Megan‘s Necklace(构造,欧拉回路,传递闭包)

本文分享了如何解决一道名为CF1361C的题目,涉及项链构造的传递性问题,通过欧拉回路找到可能的连接方式,最终使用并查集优化,时间复杂度为O(n log n)。

CF1361C. Johnny and Megan’s Necklace

Solution

真duliu,快做吐了。。。

刚开始想了一个假做法(但前面还是很真的)。

假的做法大概是你发现这个东西具有传递性,因此你考虑把aia_iai翻转后在后面补0直到20位之后,从小到大枚举iii,验证答案是否为20−i20-i20i

然后把从高到低的20−i20-i20i位相同的点之间都连上边。

因为一些特殊的传递性a  xor  b≥2x,b  xor  c≥2y→a  xor  c≥2min(x,y)a\;xor\;b\geq 2^x,b\;xor\;c\geq 2^y\to a\;xor\;c\geq 2^{min(x,y)}axorb2x,bxorc2yaxorc2min(x,y)),所以我们只需要相邻连边,并查集维护,然后就可以缩点,在新图上有若干条边,要把它们都接起来。

然后就假在我以为这题性质特殊,可以直接用set模拟一遍求出方案。但实际上这是一个欧拉回路问题,我们把边连上之后有解的条件为存在包含所有边的欧拉回路,因此我们连边之后跑欧拉回路即可。

时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)。(记得加当前弧优化!)。

Code

#include <bits/stdc++.h>

using namespace std;

template<typename T> inline bool upmin(T &x, T y) { return y < x ? x = y, 1 : 0; }
template<typename T> inline bool upmax(T &x, T y) { return x < y ? x = y, 1 : 0; }

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int, int> PR;
typedef vector<int> VI; 

const lod eps = 1e-9;
const lod pi = acos(-1);
const int oo = 1 << 30;
const ll loo = 1ll << 60;
const int mods = 998244353;
const int MAXN = 2200005;
const int INF = 0x3f3f3f3f; //1061109567
/*--------------------------------------------------------------------*/

namespace FastIO{
	constexpr int SIZE = (1 << 21) + 1;
	int num = 0, f;
	char ibuf[SIZE], obuf[SIZE], que[65], *iS, *iT, *oS = obuf, *oT = obuf + SIZE - 1, c;
	#define gc() (iS == iT ? (iT = ((iS = ibuf) + fread(ibuf, 1, SIZE, stdin)), (iS == iT ? EOF : *iS ++)) : *iS ++)
	inline void flush() {
		fwrite(obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	inline void putc(char c) {
		*oS ++ = c;
		if (oS == oT) flush();
	}
	inline void getc(char &c) {
		for (c = gc(); (c < 'a' || c > 'z') && c != EOF; c = gc());
	}
	inline void reads(char *st) {
		char c;
		int n = 0;
		getc(st[++ n]);
		for (c = gc(); c >= 'a' && c <= 'z' ; c = gc()) st[++ n] = c;
	}
	template<class I>
	inline void read(I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9' ; c = gc()) if (c == '-') f = -1;
		for (x = 0; c >= '0' && c <= '9' ; c = gc()) x = (x << 3) + (x << 1) + (c & 15);
		x *= f;
	}
	template<class I>
	inline void print(I x) {
		if (x < 0) putc('-'), x = -x;
		if (!x) putc('0');
		while (x) que[++ num] = x % 10 + 48, x /= 10;
		while (num) putc(que[num --]);
	}
	struct Flusher_{~Flusher_(){flush();}} io_Flusher_;
}
using FastIO :: read;
using FastIO :: putc;
using FastIO :: reads;
using FastIO :: print;


vector<int> Ans;
int start[MAXN], a[MAXN], b[MAXN], vis[MAXN], d[MAXN], head[MAXN], id[MAXN], n, N, edgenum, Num, opt = 0;
struct enode{ int nxt, to, u, v; } e[MAXN];

void add(int u, int v, int U, int V) {
	e[++ edgenum] = (enode){head[u], v, U, V}, head[u] = edgenum;
}
void dfs(int x) {
	for (int &i = start[x]; i ; i = e[i].nxt) {
		int t = i;
		if (vis[t]) continue;
		vis[t] = vis[t ^ 1] = 1;
		dfs(e[t].to);
		if (opt) Ans.PB(e[t].v), Ans.PB(e[t].u);
		else ++ Num, ++ Num;
	}
}
int check(int t) {
	edgenum = 1;
	for (int j = 0; j < 1 << 20 ; ++ j) head[j] = d[j] = vis[j] = 0;
	for (int j = 1; j <= n ; ++ j) {
		int x = (b[j * 2 - 1] >> t), y = (b[j * 2] >> t);
        add(x, y, j * 2 - 1, j * 2);
		add(y, x, j * 2, j * 2 - 1);
		++ d[x], ++ d[y];
	}
	int flag = 0;
	for (int j = 0; j < 1 << 20 ; ++ j) flag |= (d[j] & 1), start[j] = head[j];
	if (!flag) {
		Num = (opt ? INF : 0);
		dfs(b[1] >> t);
		if (Num < N) return 0;	
		return 1;
	}
	return 0;
}
signed main() {
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
#endif
	read(n), N = n << 1;
	for (int i = 1; i <= n ; ++ i) read(a[i * 2 - 1]), read(a[i * 2]);
	for (int i = 1; i <= N ; ++ i) 
		for (int j = 0; j < 20 ; ++ j) b[i] = b[i] << 1 | (a[i] & 1), a[i] >>= 1;
	int l = 0, r = 20;
	while (l < r) {
		int mid = (l + r) >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	opt = 1, check(r);
	print(20 - r), putc('\n');
	for (auto v : Ans) print(v), putc(' ');
	return 0;
}
本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值