【LOJ 3130】Praktični(线性基)

news/2024/11/28 20:53:42/

Praktični

题目链接:LOJ 3130

题目大意

给你一个无向图,边有边权,你每次修改可以选一个边集以及一个数,把边集里的每条边的边权都疑惑上这个数。
问你最少要修改多少次使得每个简单环的边权异或和都是 0。

思路

首先发现只有环上的要修改,考虑怎么寻找环。
那不难想象可以维护一个生成树(森林),看每次加进来的边两点是否已经连通。

那出现一个环之后,你考虑试着求出它一开始的值。
那你就是树上的的路径的异或和再异或上非树边的权值。
那树上的话我们可以先弄出生成树,然后推下去得到到根的路径的异或和,那两个点之间的就是直接两个到根的异或起来。

那考虑如果是 000 就不用管,如果不是 000 要怎么修改。
那每次是一个边集,那大概 log⁡V\log VlogV 个数就可以构造出所有的数,那我们不难想到线性基。
那在什么地方修改呢,其实会发现直接在非树边修改就好。这样有一个好处是上面我们维护的到根的异或和就不需要动态维护修改了。
而且这样一定是可能的,树上的一次修改一定可以被拆解成若干个非树边(这些非树边找到的环包含这条树边),那如果一个非树边多次异或了某个值,就奇数留下偶数消掉,所以一定是可以有方案的。

至于怎么线性基找方案(发现之前没有写过),你就把弄好的线性基拿来,从高往低,再记录下所有非树边需要异或的数。
那从高往低扫,线性基中每次找到一个数,就全部要异或的数都看一次,如果这一位有值就要异或上这个线性基上的数。
然后就找到方案了。

代码

#include<map>
#include<cstdio>
#include<vector> 
#include<algorithm>using namespace std;const int N = 1e5 + 100;
struct node {int id, x, to, nxt;
}e[N << 1];
int n, m, le[N], KK, b[N];
int p[33], a[N], tot;
vector <int> ans;
bool in[N], fx[N];
map <int, int> dy; void add(int x, int y, int z, int id) {e[++KK] = (node){id, z, y, le[x]}; le[x] = KK;
}bool insert(int x) {for (int i = 31; i >= 0; i--)if ((x >> i) & 1) {if (!p[i]) {p[i] = x; return 1;}x ^= p[i];}return 0;
}void build(int now, int father) {in[now] = 1;for (int i = le[now]; i; i = e[i].nxt)if (e[i].to != father) {if (!in[e[i].to]) {a[e[i].to] = a[now] ^ e[i].x;build(e[i].to, now);}else if (!fx[e[i].id]) {fx[e[i].id] = 1;int x = a[now] ^ a[e[i].to] ^ e[i].x;b[e[i].id] = x;tot += insert(x); }}
}int main() {scanf("%d %d", &n, &m);for (int i = 1; i <= m; i++) {int x, y, z; scanf("%d %d %d", &x, &y, &z);add(x, y, z, i); add(y, x, z, i);}build(1, 0);printf("%d\n", tot);for (int i = 31; i >= 0; i--) {if (!p[i]) continue;printf("%d ", p[i]);ans.clear();for (int j = 1; j <= m; j++) if (fx[j] && ((b[j] >> i) & 1)) {ans.push_back(j);b[j] ^= p[i];}printf("%d", ans.size());for (int j = 0; j < ans.size(); j++) printf(" %d", ans[j]);printf("\n");}return 0;
}

http://www.ppmy.cn/news/3374.html

相关文章

SpringBoot:模块探究之spring-boot-autoconfigure

顾名思义&#xff0c;Autoconfigure 就是自动配置的意思&#xff0c;SpringBoot 通过 spring-boot-autoconfigure 体现了 “约定优于配置” 这一设计原则&#xff01;spring-boot-autoconfigure 也是 SpringBoot 最重要的模块之一&#xff01; SpringBoot 则可以依据 classpath…

qt的移植

1、下载qt-everywhere-opensource-src-4.8.1.tar.gz, 下载连接地址如下:http://download.qt.io/archive/qt/4.8/4.8.1/ 2. 解压qt压缩文件tar xvf qt-everywhere-opensource-src-4.8.1.tar.gz 3. 为了编译的方便编译 &#xff0c;写了一个配置文件bulid.sh 内容如下&#xff1a…

基于springboot在线答疑系统

教师权限&#xff1a;首页、个人中心、疑难解答管理、试卷管理、试题管理、考试管理。 学生权限&#xff1b;首页、个人中心、问题发布管理、疑难解答管理、考试管理等功能模块的管理维护等操作&#xff0c;系统结构图如下图4-1所示。 图4-1 系统功能图 截图 目 录 摘 要 I …

C++初阶作业 Stackqueue 作业题一

作者&#xff1a;小萌新 专栏&#xff1a;C初阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;实现几道Stack和queue的作业题 Stack queue作业题最小栈问题栈的压入弹出序列逆波兰表达式问题总结最小栈问题 它问题的题目描述是这…

volatile,wait,notify关键字

文章目录一、volatile关键字二、wait 和 notifywaitnotifynotifyAllwait 和 sleep 的区别顺序打印ABC一、volatile关键字 volatile关键字的存在是用来解决内存可见性问题的。 我在 &#xff1a;线程安全问题 这篇文章中介绍过内存可见性问题。 前面我们讨论内存可见性时说了,…

识破贷后资金归集——关联网络

近几年&#xff0c;金融机构为了扩大信贷规模&#xff0c;抢占市场份额&#xff0c;通过贷款将贷款发放给无法直接通过金融机构获得贷款的个人或者企业&#xff0c;但这也给金融机构带来了多重风险。 首先&#xff0c;我们来看下资金归集是什么。所谓资金归集&#xff0c;是银…

Mapbox 与 Babylon.js 可视化 glsl 特效篇(三十六)

我决定不从Babylonjs 基础来讲了 直接整合mapbox与babylonjs可视化来讲 我整合一个类库 后续不断更新中 npm i haibalai/mapbox-babylonjs 初始化mapbox-babylonjs 类库&#xff0c; map 是mapbox.gl 的map 对象 import { BabylonMapManager } from “haibalai/mapbox-baby…

为什么mac电脑识别不出来u盘?macbook识别不了u盘的解决办法

为什么mac电脑识别不出来u盘&#xff1f;关于U盘插入Mac电脑无反应的情况有很多种&#xff0c;是电脑无法识别U盘&#xff1f;电脑上面没有U盘的图标&#xff1f;还是插入后无法对U盘进行写入&#xff1f;针对不同的情况&#xff0c;解决的方法也是不一样的。现在&#xff0c;我…