BZOJ4644: 经典傻逼题【线段树分治】【线性基】
Description
这是一道经典傻逼题,对经典题很熟悉的人也不要激动,希望大家不要傻逼。
考虑一张N个点的带权无向图,点的编号为1到N。 对于图中的任意一个点集
(可以为空或者全集),所有恰好有一个端点在这个点集中的边组成的集合被称
为割。 一个割的权值被定义为所有在这个割上的边的异或和。
一开始这张图是空图, 现在,考虑给这张无向图不断的加边, 加入每条边之
后,你都要求出当前权值最大的割的权值, 注意加入的边永远都不会消失。
Input
输入的第一行包括一个数ID表示数据编号, 如第一组数据中的ID = 1。注意
样例数据中的ID = 0。
接下来的第一行包括两个整数N,M表示图的点数和总共加的边。
接下来M行,每行三个正整数x,y,w表示在点x和点y之间加入一条权值为w的边。
注意x和y可能相同,两条不同的边也可能连接了同一对点。
此外, w将以二进制形式从高位向低位给出,比如, 6 = 110(2),因此如果边
权为 6,那么w将会是110。
1 ≤ N≤ 500, 1 ≤ M ≤ 1000, 0 ≤ L < 1000, 1 ≤ x,y≤ N
Output
输出M行,按顺序输出每一条边加入之后权值最大的割的权值。
同样,你也要以二进制形式输出,形式和输入格式中描述的形式一样。
Sample Input
0
3
6
1 2 1
1 2 1
3 3 111
1 3 101101
1 2 1011
2 3 111011
Sample Output
1
0
0
101101
101101
110000
HINT
前三条边加入之后的答案较为显然,考虑后三条边,加入第六条边之前, 考
虑点集{1,2},它对应的割只有第四条边, 因此答案就是第四条边的权值,考虑加
入最后一条边以后的情况,此时点集{1,2}对应的割变成了第四条边和第六条边组
成的集合,权值也发生了相应的改变。 点集{2}对应的割是第五条边和第六条边
组成的集合, 可以证明这就是权值最大的割,权值为\(1011(2)\bigoplus111011(2) =110000(2)\)
要是不知道啥是线段树分治,啥是线性基,这题这辈子不可能会做出来的
但是身为一个菜鸡,就算知道了我也照样做不出来
毕竟还是一道很好的题
很巧妙地运用了线段树分治这个方法,也让我对模型的转化有了更加深刻的认识
思路
因为直接维护边的权值非常的不方便
而且异或又有一些神奇的性质吗,所以可以考虑把边的权值转移到点上
如果一条边的两个端点都被选择了那么显然是这条边没有贡献
那就让每个点的权值等于连接到这个点上的所有边的权值的异或和
这样显然选出来点集和割的贡献就是点集权值的异或和
所以就只需要考虑点了
那么因为会像图中加入新的边,所以每个点在每个时间的权值可能是不一样的,所以就考虑用线段树分治来实现
这样就只需要算出每个时间对应的最大值就可以了
这个东西可以维护一个线性基来做
然后就做完了
我真是个傻逼
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 1e3 + 10;
const int LEN = 1e3;
typedef bitset<N> bittyp;
void Read(bittyp &x) {
static char s[N];
scanf("%s", s);
int len = strlen(s);
reverse(s, s + len);
x.reset();
fu(i, 0, len - 1) x[i] = s[i] - '0';
}
void Write(bittyp x) {
if (!x.any()) {
putchar('0');
return;
}
int pos;
fd(i, LEN, 0) if (x.test(i)) {
pos = i;
break;
}
fd(i, pos, 0) {
if (x.test(i)) putchar('1');
else putchar('0');
}
}
struct Basis {
bittyp b[N];
void clear() {
fu(i, 0, LEN) b[i].reset();
}
void insert(bittyp x) {
fd(i, LEN, 0) {
if (x[i]) {
if (!b[i].any()) {
b[i] = x;
break;
}
x ^= b[i];
}
}
}
bittyp query_max() {
bittyp res;
fd(i, LEN, 0) {
if (!res[i] && b[i].any()) {
res ^= b[i];
}
}
return res;
}
};
#define LD (t << 1)
#define RD (t << 1 | 1)
vector<bittyp> g[N << 2];
void modify(int t, int l, int r, int ql, int qr, bittyp vl) {
if (ql <= l && r <= qr) {
g[t].push_back(vl);
return;
}
int mid = (l + r) >> 1;
if (qr <= mid) modify(LD, l, mid, ql, qr, vl);
else if (ql > mid) modify(RD, mid + 1, r, ql, qr, vl);
else {
modify(LD, l, mid, ql, mid, vl);
modify(RD, mid + 1, r, mid + 1, qr, vl);
}
}
void dfs(int t, int l, int r, Basis now) {
fv(i, g[t]) now.insert(g[t][i]);
if (l == r) {
Write(now.query_max());
putchar('\n');
return;
}
int mid = (l + r) >> 1;
dfs(LD, l, mid, now);
dfs(RD, mid + 1, r, now);
}
int n, m;
int las[N];
bittyp val[N];
int main() {
int ID; Read(ID);
Read(n), Read(m);
fu(i, 1, m) {
int u, v; bittyp w;
Read(u), Read(v), Read(w);
if (u == v) continue;
if (las[u]) modify(1, 1, m, las[u], i - 1, val[u]);
las[u] = i, val[u] ^= w;
if (las[v]) modify(1, 1, m, las[v], i - 1, val[v]);
las[v] = i, val[v] ^= w;
}
fu(i, 1, n) modify(1, 1, m, las[i], m, val[i]);
Basis rt;
rt.clear();
dfs(1, 1, m, rt);
return 0;
}
BZOJ4644: 经典傻逼题【线段树分治】【线性基】的更多相关文章
- $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基
正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ...
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)
Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...
- LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset
题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...
- 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横
不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...
- BZOJ4644 : 经典傻逼题
设每个点的权值为和它相连的所有边的权值的异或和,那么等价于选若干个点,使得点权异或和最大,这显然只需要维护一组线性基,然后从高位到低位贪心选取即可. 对于本题,因为有修改操作,所以考虑按时间分治,并用 ...
- Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...
- BZOJ4184:shallot(线段树分治,线性基)
Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱 ...
- bzoj 4184 shallot——线段树分治+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4184 本来想了可持久化trie,不过空间是 nlogn (出一个节点的时候把 tot 复原就 ...
随机推荐
- MyBatis—动态SQL
什么是动态SQL? 1.基于OGNL表达式 2.完成多条件查询的逻辑 3.动态SQL的主要元素 (if,trim,where,set,choose,foreach) where标签 可以根据if中是否 ...
- 机器学习实战python3 Logistic Regression
代码及数据:https://github.com/zle1992/MachineLearningInAction logistic regression 优点:计算代价不高,易于理解实现,线性模型的一 ...
- 2018 Multi-University Training Contest 10 Solution
A - Problem A.Alkane 留坑. B - Problem B. Beads 留坑. C - Problem C. Calculate 留坑. D - Problem D. Permut ...
- C++ Primer 5th Edition自学笔记(1)
好吧,第一次写东西...如何下手呢...(请无视) -------------------------------------------------------------- Chapter 1. ...
- Qt信号和槽连接方式的选择
看了下Qt的帮助文档,发现connect函数最后还有一个缺省参数. connect函数原型是这样的: QMetaObject::Connection QObject::connect(const QO ...
- Django:提交表单时遇到403错误:CSRF verification failed
Django:提交表单时遇到403错误:CSRF verification failed 问题: 提交表单时遇到403错误:CSRF verification failed 解决方案: 在表单界面ht ...
- 20145314郑凯杰《网络对抗技术》实验1 逆向及Bof基础实践
20145314郑凯杰<网络对抗技术>实验1 逆向及Bof基础实践 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数 ...
- 从0开始学习 GITHUB 系列之「GIT 进阶」【转】
本文转载自:http://stormzhang.com/github/2016/06/16/learn-github-from-zero5/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...
- 注解装配Bean
@Service用于标注业务层组件@Controller用于标注控制层组件@Repository用于标注数据访问组件,即DAO组件@Component泛指组件,当组件不好归类的时候,我们可以使用这个注 ...
- pyenv 让 python 版本完美切换
前言 我觉得如果使用 python 开发的话,还是在 unix/linux 的环境下吧,shell 工具的效率比 windows 高得多,尽管 windows 下也有 cmder 这种神器,而且现在 ...