Description

题库链接

小 \(S\) 现在拥有 \(n\) 座城市,第 \(i\) 座城市的人口为 \(w_i\) ,城市与城市之间可能有双向道路相连。

现在小 \(S\) 要将这 \(n\) 座城市划分成若干个州,每个州由至少一个城市组成,每个城市在恰好一个州内。

假设小 \(S\) 将这些城市划分成了 \(k\) 个州,设 \(V_i\) 是第 \(i\) 个州包含的所有城市组成的集合。 定义一条道路是一个州的内部道路,当且仅当这条道路的两个端点城市都在这个州内。 如果一个州内部存在一条起点终点相同,不经过任何不属于这个州的城市,且经过这个州的每个城市至少一次、所有内部道路都恰好一次的路径(路径长度可以为 \(0\) ),则称这个州是不合法的。

定义第 \(i\) 个州的满意度为:第 \(i\) 个州的人口在前 \(i\) 个州的人口中所占比例的 \(p\) 次幂,即:

\[\left (\frac{\sum_{x \in V_i}{w_x}}{\sum_{j=1}^{i}\sum_{x \in V_j}{w_x}}\right )^p\]

定义一个划分的满意度为所有州的满意度的乘积,求所有合法的划分方案的满意度之和,答案对 \(998244353\) 取模。

两个划分 \(\{V_1\cdots V_k\}\) 和 \(\{C_1\cdots C_s\}\) 是不同的,当且仅当 \(k\neq s\) ,或存在某个 \(1\leq i\leq k\) ,使得 \(Vi\neq Ci\) 。

\(0\leq n\leq 21,0\leq m\leq \frac{n\times (n-1)}{2},0\leq p\leq 2,1\leq w_i\leq 100\)

Solution

我们记 \(f_S\) 为选点情况为 \(S\) 时,划分成若干非空集合所得到的所有贡献。

容易得到转移方程:

\[f_S=\frac{1}{sum_S^p}\sum_{X\subset S} f(X)sum_{S-X}^P\]

其中 \(sum_S\) 表示点集 \(S\) 中所有点的权值和。

那么套路地用子集卷积搞一下就好了。注意要预处理出满足条件的集合。

安利我博客:子集卷积

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 21+5, SIZE = (1<<21)+5, yzh = 998244353; int n, m, p, u, v, w[N], mp[N][N], bin[N];
int f[N][SIZE], g[N][SIZE], ok[SIZE], sum[SIZE], inv[SIZE], cnt[SIZE];
int fa[N], deg[N];
int find(int o) {return fa[o] ? fa[o] = find(fa[o]) : o; } int quick_pow(int a, int b) {
int ans = 1;
while (b) {
if (b&1) ans = 1ll*ans*a%yzh;
b >>= 1, a = 1ll*a*a%yzh;
}
return ans;
}
void FMT(int *A, int o) {
for (int i = 1; i < bin[n]; i <<= 1)
for (int j = 0; j < bin[n]; j++)
if (i&j) (A[j] += A[i^j]*o) %= yzh;
}
bool judge(int S) {
for (int i = 1; i <= n; i++) if (bin[i-1]&S) sum[S] += w[i], ++cnt[S], fa[i] = deg[i] = 0;
int b = cnt[S];
for (int i = 1; i <= n; i++) if (S&bin[i-1])
for (int j = i+1; j <= n; j++) if ((S&bin[j-1]) && mp[i][j]) {
++deg[i], ++deg[j];
if (find(i)^find(j)) fa[find(i)] = find(j), --b;
}
if (b > 1) return true;
for (int i = 1; i <= n; i++) if ((S&bin[i-1]) && (deg[i]&1)) return true;
return false;
}
void work() {
scanf("%d%d%d", &n, &m, &p); bin[0] = 1;
for (int i = 1; i <= 25; i++) bin[i] = bin[i-1]<<1;
for (int i = 1; i <= m; i++) {
scanf("%d%d", &u, &v); mp[u][v] = mp[v][u] = 1;
}
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
for (int i = 0; i < bin[n]; i++) ok[i] = judge(i);
for (int i = 0; i < bin[n]; i++) {
sum[i] = quick_pow(sum[i], p);
inv[i] = quick_pow(sum[i], yzh-2);
if (ok[i]) g[cnt[i]][i] = sum[i];
}
for (int i = 0; i <= n; i++) FMT(g[i], 1);
f[0][0] = 1; FMT(f[0], 1);
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++)
for (int k = 0; k < bin[n]; k++)
(f[i][k] += 1ll*f[j][k]*g[i-j][k]%yzh) %= yzh;
FMT(f[i], -1);
for (int k = 0; k < bin[n]; k++) f[i][k] = 1ll*f[i][k]*inv[k]%yzh;
for (int k = 0; k < bin[n]; k++) if (cnt[k] != i) f[i][k] = 0;
if (i != n) FMT(f[i], 1);
}
printf("%d\n", (f[n][bin[n]-1]+yzh)%yzh);
}
int main() {work(); return 0; }

[WC 2018]州区划分的更多相关文章

  1. 解题:WC 2018 州区划分

    题面 WC之前写的,补一补,但是基本就是学新知识了 首先可以枚举子集$3^n$转移,优化是额外记录每个集合选取的个数,然后按照选取个数从小到大转移.转移的时候先FWT成“点值”转移完了IFWT回去乘逆 ...

  2. WC 2018 题解

    WC 2018 题解 一些感受.jpg 题目难度相较前些年会相对简单一点?(FAKE.jpg 平均码量符合WC风格?(甚至更多一点 出题人良心! [WC2018] 通道 一个不知道对不对的$\log ...

  3. WC 2018/CTSC 2018/APIO 2018 游记

    (要写CTSC的时候才想起来没写WC2018,那就粗略回顾一下吧hhhhh) WC 2018(简略版): 大概和 一个宁夏和一个天津的大哥一个宿舍hhhh,字典序分宿舍真是奇妙. WC讲课真的不是人听 ...

  4. UOJ#348. 【WC2018】州区划分

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 ...

  5. [WC2018]州区划分——FWT+DP+FST

    题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...

  6. 【WC2018】州区划分(FWT,动态规划)

    [WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ...

  7. [WC2018]州区划分

    [WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ...

  8. 「WC2018」州区划分(FWT)

    「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...

  9. UOJ348. 【WC2018】州区划分

    UOJ348. [WC2018]州区划分 http://uoj.ac/problem/348 分析: 设\(g(S)=(\sum\limits_{x\in S}w_x)^p[合法]\) \(f(S)\ ...

随机推荐

  1. Jersey Client传递中文参数

    客户端需要客户端的包: <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jerse ...

  2. Alwayson--与复制的影响

    在主副本上建立复制后,复制的事务日志读取代理(log reader)不会读取尚未同步到辅助副本的日志,因为辅助副本可能在下一时刻转化成为主副本,变为新的复制发布服务器,为此需要保证复制处理的日志总慢于 ...

  3. python 模拟普通用户和管路员登录购物系统小程序

    程序功能描述如下:不同角色登录,普通用户可以查看商品购买商品.查看购物车和余额.退出:管理员可以充值,可以添加商品.退出 用户信息字典格式: { '', 'money': 14435.76, 'car ...

  4. asp.net 进行发送邮箱验证

    利用发送邮件验证码进行注册验证 需要引用using System.Net.Mail;命名空间 #region /// <summary> /// 发送邮件 /// </summary ...

  5. flume在windows环境下的使用

     Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理, ...

  6. 配置阿里yum源,设置命令

    配置阿里yum源 #linux的软件包管理 安装 软件的方式有三种 .源代码编译安装() .下载python3的源代码 .解压缩源代码 .进入源代码目录,开始编译安装 .配置环境变量 .yum方式安装 ...

  7. 七,apache配置域名

    配置域名服务器流程: (1)在httpd.conf中启用虚拟主机,Include conf/extra/httpd-vhosts.conf前面的#去掉. (2)在httpd.conf中修改项目路径为自 ...

  8. Android之自定义控件

    开发自定义控件的步骤: 1.了解View的工作原理  2. 编写继承自View的子类 3. 为自定义View类增加属性  4. 绘制控件  5. 响应用户消息  6 .自定义回调函数    一.Vie ...

  9. HTML+纯JS制作音乐播放器

    该篇文章会教你通过JavaScript制作一个简单的音乐播放器.包括播放.暂停.上一曲和下一曲. 阅读本文章你需要对HTML.CSS和Javascript有基本的了解. 话不多说,先上图. emmm. ...

  10. Vue+Flask看这篇就够了

    一.项目目录结构 使用Vue+Flask搭建前后端分离的基础平台. my_project/ app/ //vue目录 static/ models/ remplates/ 404.html index ...