【线性基 集合hash】uoj#138. 【UER #3】开学前的涂鸦
还需要加强分析题目特殊性质,设计对应特殊算法,少想多写大力dfs剪枝不要管MLETLE直接上的能力
红包是一个有艺术细胞的男孩子。
红包由于NOI惨挂心情不好,暑假作业又多,于是他开始在作业本上涂鸦。
一开始,他在纸上画了一棵 nn 个节点的树。但是他觉得这样的画太简单了,体现不出他高超的绘画功底,于是他又额外画上了 kk 条边。
然而他觉得这样画面太复杂,于是想删去一些边使得这个无向图仍然是连通的。
请帮红包求出删边的方案数。两个方案被认为是不同的当且仅当存在一条边在其中一组中被删而另一组中没有。(什么边都不删也算一种方案)
输入格式
第一行两个整数,n,kn,k。保证 1≤n≤105,k≥01≤n≤105,k≥0。
接下来 n−1n−1 行,描述了红包最开始画的那颗树。每行两个整数 v,uv,u 表示 vv 和 uu 之间有一条无向边。
接下来 kk 行,描述了红包后来加的边。每行两个整数 v,uv,u 表示红包在 vv 和 uu 之间又加上了一条边。数据保证树中原有的边不会被再添加一次且 v≠uv≠u。
保证 1≤v,u≤n1≤v,u≤n。
输出格式
一个整数,表示方案数。你只用输出答案对 998244353998244353(7×17×223+17×17×223+1,一个质数)取模后的值。
题目分析
关于离线维护动态图连通性有一种常见套路:处理出原图的一颗dfs树,再为每一条非树边随机分配一个权值,剩下的树边权值就是所有经过它的非树边权值异或和。那么选出的边集对原图连通性没有影响当且仅当该边集的权值两两线性无关。
之前做过一题的套路就是这样的:【思维题 集合hash 树上差分】11.5撸树
关于这个随机化算法的证明,网上找到两篇高质量的证明 “图不连通 iff 删掉边集的权值线性相关”,
对于这题,首先注意到k不大,那么就不需要常规做法的双哈希pair,而是直接将第i条非树边权值设为$2^{i-1}$.这样一来就能够在保证正确性的前提下减少常数。第二,如何求一个集合的线性无关子集个数?注意到这里的线性无关子集大小与集合元素种类都是和k同阶的。然后就可以用 算法七 的暴力dfs寻找线性无关子集数量,而因为“线性无关”这道剪枝“十分有力”,所以uoj榜上这个做法吊打标算……
#include<bits/stdc++.h>
#define MO 998244353
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ; struct Edge
{
int v,id;
Edge(int a=, int b=):v(a),id(b) {}
}edges[maxm];
struct node
{
ull val,cnt;
}a[maxm];
struct LinearBasis
{
ull a[];
bool insert(ull x)
{
for (int i=,chk=; i>=&&!chk; i--)
if ((x>>i)&){
if (a[i]) x ^= a[i];
else a[i] = x, chk = true;
}
return x > ;
}
};
int n,k,m,cnt,u[],v[];
int edgeTot,head[maxn],nxt[maxm];
ull eval[maxm],enod[maxn];
long long ans; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v, int id)
{
edges[++edgeTot] = Edge(v, id), nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = Edge(u, id), nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void color(int x, int fa)
{
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].v, id = edges[i].id;
if (v==fa) continue;
color(v, x), enod[x] = enod[x]^enod[v], eval[id] = enod[v];
}
}
void dfs(int x, LinearBasis s, int c)
{
if (x==cnt+) ans = (ans+c)%MO;
else{
dfs(x+, s, c);
if (s.insert(a[x].val))
dfs(x+, s, 1ll*c*a[x].cnt%MO);
}
}
int main()
{
memset(head, -, sizeof head);
n = read(), k = read();
for (int i=; i<n; i++)
addedge(read(), read(), i);
for (int i=; i<=k; i++)
u[i] = read(), v[i] = read(), eval[i+n-] = (ull)1ll<<i,
enod[u[i]] = enod[u[i]]^eval[i+n-], enod[v[i]] = enod[v[i]]^eval[i+n-];
color(, );
m = n+k-;
std::sort(eval+, eval+m+);
for (int i=,j=; i<=m; i=j)
if (eval[i]){
for (j=i; eval[j]==eval[i]&&j<=m; j++);
a[++cnt].val = eval[i], a[cnt].cnt = j-i;
}else ++j;
dfs(, LinearBasis(), );
printf("%lld\n",ans);
return ;
}
END
【线性基 集合hash】uoj#138. 【UER #3】开学前的涂鸦的更多相关文章
- UOJ #138. 【UER #3】开学前的涂鸦
Description 红包是一个有艺术细胞的男孩子. 红包由于NOI惨挂心情不好,暑假作业又多,于是他开始在作业本上涂鸦. 一开始,他在纸上画了一棵 n 个节点的树.但是他觉得这样的画太简单了,体现 ...
- bzoj4568: [Scoi2016]幸运数字(LCA+线性基)
4568: [Scoi2016]幸运数字 题目:传送门 题解: 好题!!! 之前就看过,当时说是要用线性基...就没学 填坑填坑: %%%线性基 && 神犇 主要还是对于线性基的运用和 ...
- [CQOI2013]新Nim游戏(博弈论,线性基)
[CQOI2013]新Nim游戏 题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根 ...
- HDU - 3949 :XOR(线性基,所有集合的不同异或和中,求从小到大第K个)
XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A ...
- uoj#36. 【清华集训2014】玛里苟斯(线性基+概率期望)
传送门 为啥在我看来完全不知道为什么的在大佬们看来全都是显然-- 考虑\(k=1\)的情况,如果序列中有某一个\(a_j\)的第\(i\)位为\(1\),那么\(x\)的第\(i\)位为\(1\)的概 ...
- UOJ #36 -【清华集训2014】玛里苟斯(线性基+暴搜)
UOJ 题面传送门 看到 \(k\) 次方的期望可以很自然地想到利用低次方和维护高次方和的套路进行处理,不过.由于这里的 \(k\) 达到 \(5\),直接这么处理一来繁琐,二来会爆 long lon ...
- UOJ#36. 【清华集训2014】玛里苟斯 线性基
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ36.html 题解 按照 $k$ 分类讨论: k=1 : 我们考虑每一位的贡献.若有至少一个数第 $i$ ...
- BZOJ.3811.玛里苟斯(线性基)
BZOJ UOJ 感觉网上大部分题解对我这种数学基础差的人来说十分不友好...(虽然理解后也觉得没有那么难) 结合两篇写的比较好的详细写一写.如果有错要指出啊QAQ https://blog.csdn ...
- Xor && 线性基练习
#include <cstdio> #include <cstring> ; ; int cnt,Ans,b,x,n; inline int Max(int x,int y) ...
随机推荐
- ES6工作中常用知识点
好久不动笔了 第一个知识点:import 和 export import导入模块.export导出模块 //全部导入 import people from './example' //有一种特殊情况, ...
- jQuery树形控件zTree使用
http://www.cnblogs.com/AutumnRhyme/p/5915769.html .................................................. ...
- ros indigo install
http://wiki.ros.org/cn/indigo/Installation/Ubuntu
- C++之struct
C++的struct对C做和很多补充,里面可以放函数(构造函数和虚函数),也可以同struct和class的继承,在C++中也完全可以替代class.他们之间的主要区别: 1 calss默认是私有继承 ...
- Spark Mllib里如何采用保序回归做回归分析(图文详解)
不多说,直接上干货! 相比于决策树,保序回归的应用范围没有决策树算法那么广泛. 特别在数据处理较为庞大的时候,采用保序回归做回归分析,可以极大地节省资源,从而提高计算效率. 保序回归的思想,是对数据进 ...
- Python编程实现USB转RS485串口通信
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:Python编程 ...
- IE6下float双边距问题
当浮动元素的方向和设置margin的方向相同时,就会出现双边距问题,解决方法是: 删除浮动,改成display:inline-block _display:inline; _zoom:1;
- EBS应用重启
重启系统应用 cd $ADMIN_SCRIPTS_HOME ./adstpall.sh apps/apps ./adstrtal.sh apps/apps 在重启应用时,可能会出现并发管理器未启动的情 ...
- Cocos2d-x v3.1 安装图文教程(二)
Cocos2d-x v3.1 安装图文教程(二) 如果我们需要在Android平台上运行就必须安装android的SDK,如果我们只想在window上运行就只需要安装Cocos2d-x就行了.当 ...
- fancyBox高级进阶用法
最近给客户做的一个项目中,客户要求弹窗的边界与页面某个区块边界平齐,但平齐之后,弹出的窗口就不是居中的情况了,研究之后,认为需要改写fancyBox的fancybox-wrap类中的top属性才能达到 ...