图论+线性基高斯消元与主元:1019T2 / P4151

news/2024/7/15 18:08:40 标签: 图论, 生成树, 线性基, 高斯消元, 主元

http://cplusoj.com/d/senior/p/SS231019B

相当于图上选一条链和一堆环


考虑dfs生成树

则链是两条从根出发的链

环是每条返祖边组成的环

所以环和链的异或和可以求出来


链的放到线性基

然后线性基通过高斯消元主元(贪心思想,主元可以令那一位一定为1。那么就钦定主元为必选,这样一定更优)

高消的过程中也需要对链进行消元

最后用链来查询,丢01trie上维护

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
//mt19937 rand(time(0));
//mt19937_64 rand(time(0));
//srand(time(0));
#define N 100010
//#define M
//#define mo
int n, m, i, j, k, T;
int ans, C, MY, dis[N]; 
struct line_kun {
	int p[100]; 
	void push(int k) {
//		printf("Add %lld\n", k); 
		for(int j = 62; j >= 0; --j)
			if((k>>j)&1) {
				if(!p[j]) { p[j]=k; break; }
				k^=p[j];  
			}
	}
	void xiaoyuan() {
//		for(int j = 62; j >= 0; --j) printf("%lld ", p[j]); printf("\n"); 
		for(int j = 62; j >= 0; --j)
			if(p[j]) {
				for(int i = 62; i > j; --i) 
					if((p[i]>>j)&1) p[i]^=p[j]; 
				for(int i = 1; i <= n; ++i) 
					if((dis[i]>>j)&1) dis[i]^=p[j]; 
			}
//		for(int j = 62; j >= 0; --j) printf("%lld ", p[j]); printf("\n"); 
	}
	pair<int, int> main_Y() {
		int k = (1ll<<62)-1, ans = 0; 
		for(int j = 62; j >= 0; --j) 
			if(p[j]) k-=(1ll<<j), ans^=p[j]; 
		return {k, ans}; 
	}
}J; 
struct Trie_tree {
	int tot = 1, son[N * 60][2] ; 
	int que_max(int x) {
//		printf("Que_mx : %lld\n", x); 
		int u = 1, i, k, ans=0; 
		for(i = 62; i>=0; --i) {
			k = (x>>i)&1ll; 
			if(son[u][k^1]) u=son[u][k^1], ans|=((k^1)<<i); 
			else u=son[u][k], ans|=(k<<i); 
		}
//		printf("\t We get %lld\n", ans); 
		return ans; 
	}
	void add(int x) {
		int u = 1, i, k; 
		for(i = 62; i >= 0; --i) {
			k = (x>>i)&1ll; 
			if(!son[u][k]) son[u][k] = ++tot; 
			u = son[u][k]; 
		}
	}
}Trie;
struct node {
	int y, z; 
};
int u, v, w; 
pair<int, int>p; 
vector<node>G[N]; 

void dfs(int x, int fa) {
	for(auto t : G[x]) {
		int y = t.y, z = t.z; 
//		if(t.y == fa) continue; 
		if(dis[y] == -1) {
			dis[y] = dis[x] ^ z; 
			dfs(y, x); 
		}
		else J.push(dis[x] ^ dis[y] ^ z); 
	}
}

signed main()
{
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
//	freopen("path.in", "r", stdin);
//	freopen("path.out", "w", stdout);
	T=read();
//	while(T--) {
//
//	}
	n = read(); m = read(); 
	for(i=1; i<=m; ++i) {
		u = read(); v = read(); w = read(); 
		G[u].pb({v, w}); G[v].pb({u, w}); 
	}
	memset(dis, -1, sizeof(dis)); 
	dis[1]=0; dfs(1, 0); 
//	for(i=1; i<=n; ++i) printf("%lld ", dis[i]); printf("\n"); 
	J.xiaoyuan(); 
	p = J.main_Y(); MY = p.first; C = p.second; 
//	cout<<(bitset<100>)(MY)<<endl; 
//	for(i=1; i<=n; ++i) dis[i]&=MY; 
//	printf("# %lld %lld %lld\n", MY, C, k); 
	k=C-(MY&C); C&=MY; 
//	printf("# %lld %lld %lld\n", MY, C, k); 
//	for(i=1; i<=n; ++i) printf("%lld ", dis[i]); printf("\n"); 
	Trie.add(0); 
	for(i=1; i<=n; ++i) {
		if(i==1) Trie.add(dis[i]); 
		if(i==n)  ans = max(ans, dis[i]^Trie.que_max(dis[i]^C)^C); 
	}
	printf("%lld", ans^k); 
	return 0;
}



http://www.niftyadmin.cn/n/5104476.html

相关文章

斯坦福发布 最新 GPT 模型排行榜 AlpacaEval

文章目录 &#x1f4cc;提炼❓什么是 AlpacaEval&#x1f50e;AlpacaEval 排行榜 包含的 测试 模型 和数据&#x1f4af;在不同的测试集上各个大模型的能力评分&#x1f680;AlpacaEval Leaderboard 大模型的能力综合评分&#x1f4bc; 普遍国内白领 如何快速应用 大模型&#…

Trie树/字典树的原理及实现[C/C++]

文章目录 前言引例&#xff1a;Google经典面试题字典树的原理与实现定义字典树的结构字典树的操作字符串插入字符串查询 字典树的实现字符集数组法节点类结构设计节点的接口字符映射节点类的代码实现 字典树类结构设计字典树接口实现 字符集映射法&#xff08;适用性广&#xf…

【树莓派图像处理】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Qt OPENCV 安装测试&#xff1f;运行Qt错误 二、使用步骤1.框架1. 开启摄像头2.获取显示图像的内容 2.测试 总结 前言 提示&#xff1a;这里可以添加本文要…

显示杂谈(一)Window以及WindowManager

***什么时候会用到window,当桌面需要显示一个类似与悬浮窗的东西,那就需要用到Window,而创建window则就需要windowManager *** WindowManager 添加Window简单过程 Demo //lbsButton mFloatingButton = new Button(this);mFloatingButton.setText("windowbutton-lbs&q…

MIKE水动力笔记16_MIKE中的u、v、Speed、Direction之间的关系

本文目录 前言Step 1 MIKE中u、v、Speed、Direction的界定Step 2 从MIKE中导出u、v、Speed、Direction数据Step 3 数据导入Excel验证 前言 这两天饶有兴趣的做了一下关于MIKE中u、v、Speed、Direction之间关系的小测试&#xff0c;其实主要是为了探究利用u、v得到的角度和Dire…

【MATLAB第80期】基于MATLAB的结构核岭回归SKRR多输入单输出回归预测及分类预测模型

【MATLAB第80期】基于MATLAB的结构核岭回归SKRR多输入单输出回归预测及分类预测模型 SKRR这是Gustau Camps-Valls等人在“用深度结构核回归检索物理参数”中提出的结构核岭回归&#xff08;SKRR&#xff09;方法。 参考文献&#xff1a; Camps-Valls,Retrieval of Physical Pa…

代码随想录算法训练营第二十七天丨 回溯算法part04

93.复原IP地址 思路 其实只要意识到这是切割问题&#xff0c;切割问题就可以使用回溯搜索法把所有可能性搜出来&#xff0c;和刚做过的131.分割回文串 (opens new window)十分类似。 切割问题可以抽象为树型结构&#xff0c;如图&#xff1a; ​ 回溯三部曲 递归参数 在13…

Mask R-CNN训练自己的数据集

数据集制作 通常使用labelme来制作实例分割数据集&#xff0c;也有教程和代码来转换成COCO数据集。labelme项目地址为&#xff1a;https://github.com/wkentaro/labelme/tree/main 安装labelme conda create --namelabelme python3 conda activate labelme pip install labe…