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. Node.js-Usage & Example

    Usage# node [options] [v8 options] [script.js | -e "script"] [arguments] Please see the Co ...

  2. 【加密算法】MD5

    一.简介 MD5的全称是Message-Digest Algorithm 5(信息摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data S ...

  3. Redis入门教程(C#)

    Redis是什么? Redis是一个开源的.使用C语言编写的.支持网络交互的.可基于内存也可持久化的Key-Value数据库. 补充概念: 持久化:是将程序数据在持久状态和瞬时状态间转换的机制.通俗的 ...

  4. silverlight chart 折线图 的线颜色如何修改???

    silverlight  chart 折线图 的线颜色如何修改??? 我做出来都是这些偏黄色,请问如何修改线的颜色,以及线的宽度?谢谢

  5. 第五章 企业项目开发--mybatis注解与xml并用

    本章的代码建立在第四章<Java框架整合--切分配置文件>的项目代码之上,链接如下: http://www.cnblogs.com/java-zhao/p/5118184.html 在实际 ...

  6. tomcat JNDI Resource 配置

    最近公司的项目慢慢开始向Maven项目迁移, 部分配置文件公共组也帮我们做了些改动,其中在spring的applicationContext.xml中看到了数据连接bean存在两个,一个是jndi 一 ...

  7. 更换SSL证书

    1.申请证书,需要提供完整域名(例如:xxx.aaa.com),会和证书完全匹配. 2.将证书上传到web服务器,例如我的nginx,在server中指定证书路径. 3.重启web服务器.(这个证书和 ...

  8. 【wireshark】插件开发(一):概述

    1. 概述 wireshark提供了灵活的插件机制,使用户可以方便地扩展wireshark的功能.插件的功能主要包括,但不限于协议解析器. 可以使用Lua或C语言来编写Wireshark插件,下表对比 ...

  9. 《JAVA与模式》之装饰模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述装饰(Decorator)模式的: 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替 ...

  10. HTML简单登录和注册页面及input标签诠释

    今天第一次接触HTML这种语言,虽然不能完全理解其中的意思,过去学的英语单词几乎也忘了差不多了,但是感觉进入这门语言学习之后就没有那么难了,一步一步来吧!下面巩固下今天学内容: HTML是一种超文本标 ...