yww 与连通块计数
yww 与连通块计数
分析
观察题目的额外限制,\(s1 | a_i ,a_i| s2\);\(\nexists i>1 ,i^2|s2\)
这意味着对于\(s2\)的每个因数,出现次数为\(1\)
如果把\(a_i,s1,s2\)全部除去\(gcd(s1,s2)\),那么按照剩下所有因数给\(a_i\)标记一个二进制状态\(C_i\)
那么在选择的联通块里,已经满足条件的因数集合所有的\(\{C_u \ xor \ C_v|(u,v)\in E,u \in V',v\in V'\}\)的或
因为如果出现\(C_u\)与\(C_v\)的某一位不同\(\Leftrightarrow\)就意味着这个因数已经出现了\(0,1\)两种情况,即同时满足了\(\text{GCD}\)和\(\text{LCM}\)的限制
这时候我们有两种办法计算(个人推荐Solution2哈)
设\(n\)的质因子集合为\(p\)
Solution1:FWT
对于点直接进行\(dp\)转移\(dp[u][S]\)表示当前最高点是\(u\),满足条件的因数集合是\(S\)的方案数
\(dp[u][i|j]=dp[u][i]\cdot dp[v][j]\)
由于有或的操作,所以可以用高位前缀和/\(FWT\)或卷积
在没有优化的情况下,两种做法复杂度均为\(O(n|p|2^{|p|})\)
但是不用每次都\(\text{FWT}\)过去\(\text{FWT}\)回来,所以省去之后复杂度为\(O(n\cdot 2^{|p|})\)
代码不是我的哈(@神仙Rtx)
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i(a), i##_END(b); i <= i##_END; i++)
#define drep(i, a, b) for(int i(a), i##_END(b); i >= i##_END; i--)
using namespace std;
const int maxn = 1010, mod = 1e9+7;
typedef long long ll;
vector<int> e[maxn];
int n, pr[60], cnt, v[60], hs[maxn];
ll a[maxn], s1, s2, f[maxn][(1<<15)+10], ans[(1<<15)+10];
inline void ins(ll &x, ll y) { x = (x + y >= mod ? x + y - mod : x + y); }
void init(int N) {
rep(i, 2, N) {
if(!v[i]) pr[++cnt] = i;
for(int j = 1; j <= cnt && i * pr[j] <= N; ++j)
v[i * pr[j]] = 1;
}
}
void rfwt(ll *p, int N) {
for(int mid = 1; mid < N; mid <<= 1)
for(int i = 0; i < N; i += (mid << 1))
for(int j = 0; j < mid; ++j) ins(p[i + j + mid], mod - p[i + j]);
}
void dfs(int x, int pa) {
rep(i, 0, (1<<cnt)-1) f[x][i] = 1;
rep(i, 0, e[x].size() - 1) if(e[x][i] != pa) {
int y = e[x][i];
dfs(y, x);
int diff = hs[x] ^ hs[y];
for(int s = diff; s < (1<<cnt); s = (s+1)|diff)
ins(f[x][s], f[x][s] * f[y][s] % mod);
}
rep(i, 0, (1<<cnt)-1) ins(ans[i], f[x][i]);
}
int main() {
scanf("%d%lld%lld", &n, &s1, &s2), s2 /= s1;
int x, y;
rep(i, 1, n) scanf("%lld", &a[i]), a[i] /= s1;
rep(i, 2, n) scanf("%d%d", &x, &y), e[x].push_back(y), e[y].push_back(x);
init(50);
rep(i, 1, n) rep(j, 1, cnt) if(a[i] % pr[j] == 0) hs[i] |= (1<<(j-1));
dfs(1, 0);
rfwt(ans, 1<<cnt); // 最后FWT回来就可以了
int mx = 0;
rep(i, 1, cnt) if(s2 % pr[i] == 0) mx |= (1<<(i-1));
printf("%lld\n", ans[mx]);
return 0;
}
Solution2:容斥
枚举不满足条件的因数集合为\(S\),那么必然有\((C_u \ xor \ C_v) \and S={\empty}\)
\(O(n) \ \ \text{dp}\)求解即可和上面一样,但是省去了第二维
然后就是简单的奇偶容斥了
可以看到,复杂度就是\(O(n\cdot 2^{|p|})\),跑满的
const int N=1e3+10;
int n,C[N],fac[N],fc;
ll A,B,g;
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); }
vector <int> G[N];
int S;
ll dp[N];
void dfs(int u,int f) {
dp[u]=1;
for(int v:G[u]) if(v!=f) {
dfs(v,u);
if(((C[u]^C[v])&S)==0) dp[u]=(dp[u]+dp[u]*dp[v])%P; // 按照限制dp
}
}
int main(){
n=rd(),A=rd<ll>(),B=rd<ll>(),g=gcd(A,B);
A/=g,B/=g;
rep(i,2,50) if(B%i==0) B/=i,fac[fc++]=i; // 这些是预处理因数集合
rep(i,1,n) {
ll x=rd<ll>()/g;
rep(j,0,fc-1) if(x%fac[j]==0) C[i]|=1<<j;
}
rep(i,2,n) {
int u=rd(),v=rd();
G[u].pb(v),G[v].pb(u);
}
ll ans=0;
for(S=0;S<(1<<fc);++S) { // 枚举不合法的状态
int cnt=0;
rep(i,0,fc-1) if(S&(1<<i)) cnt^=1;
dfs(1,0);
rep(i,1,n) if(cnt) ans-=dp[i];
else ans+=dp[i]; // 偶加奇减
}
ans=(ans%P+P)%P;
printf("%lld\n",ans);
}
原文地址:https://www.cnblogs.com/chasedeath/p/12743738.html
- oracle odp.net 32位/64位版本的问题
- Redis+TwemProxy(nutcracker)集群方案部署记录
- 金融科技新常态,未来开启拼“硬实力”阶段
- Mono 3 的默认Gc是Sgen
- Linux下Redis主从复制以及SSDB主主复制环境部署记录
- 单元测试同时支持 NUnit/MSTest
- log4net快速上手
- MySQL高可用方案-PXC环境部署记录
- Redis主从复制下的工作原理梳理
- Linux系统下常用的数据备份方法
- K2 的Workspace 遭遇400 RequestLength 错误修复
- 从零开始学人工智能-Python·决策树(三)·节点
- .net程序员使用Oracle新手上路指南
- python的函数(二):作用域
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一个简单的小技巧,监控网页所有动态标签创建的调用处
- SAP Spartacus storefrontapp index.html的design time和runtime
- OS开发爱好者福利来了:树莓派上编译C语言,顺便掌握一波硬件知识
- 一个简单易用的图标字体库和CSS框架fontawesome
- OLAP 数据平台 Druid 第一步,编写 Spec 配置
- 搭建 Kubernetes 集群 Dashboard 2.0+ 可视化插件
- Kubernetes 集群基本概念
- 未能幸免!安全容器也存在逃逸风险
- vue中v-for图片src路径错误
- 读书笔记 dotnet 什么时候进行垃圾回收
- Windows系统下ROS1或ROS2获取RTSP视频等功能包
- 本地存储
- 移动端click 延时解决方案
- 移动端返回顶部
- 移动端轮播图