[WC 2018]州区划分
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]州区划分的更多相关文章
- 解题:WC 2018 州区划分
		题面 WC之前写的,补一补,但是基本就是学新知识了 首先可以枚举子集$3^n$转移,优化是额外记录每个集合选取的个数,然后按照选取个数从小到大转移.转移的时候先FWT成“点值”转移完了IFWT回去乘逆 ... 
- WC 2018 题解
		WC 2018 题解 一些感受.jpg 题目难度相较前些年会相对简单一点?(FAKE.jpg 平均码量符合WC风格?(甚至更多一点 出题人良心! [WC2018] 通道 一个不知道对不对的$\log ... 
- WC 2018/CTSC 2018/APIO 2018 游记
		(要写CTSC的时候才想起来没写WC2018,那就粗略回顾一下吧hhhhh) WC 2018(简略版): 大概和 一个宁夏和一个天津的大哥一个宿舍hhhh,字典序分宿舍真是奇妙. WC讲课真的不是人听 ... 
- UOJ#348. 【WC2018】州区划分
		原文链接www.cnblogs.com/zhouzhendong/p/UOJ348.html 前言 第一次知道子集卷积可以自己卷自己. 题解 这是一道子集卷积模板题. 设 $sum[S]$ 表示点集 ... 
- [WC2018]州区划分——FWT+DP+FST
		题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ... 
- 【WC2018】州区划分(FWT,动态规划)
		[WC2018]州区划分(FWT,动态规划) 题面 UOJ 洛谷 题解 首先有一个暴力做法(就有\(50\)分了) 先\(O(2^nn^2)\)预处理出每个子集是否合法,然后设\(f[S]\)表示当前 ... 
- [WC2018]州区划分
		[WC2018]州区划分 注意审题: 1.有序选择 2.若干个州 3.贡献是州满意度的乘积 枚举最后一个州是哪一个,合法时候贡献sum[s]^p,否则贡献0 存在欧拉回路:每个点都是偶度数,且图连通( ... 
- 「WC2018」州区划分(FWT)
		「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ... 
- UOJ348. 【WC2018】州区划分
		UOJ348. [WC2018]州区划分 http://uoj.ac/problem/348 分析: 设\(g(S)=(\sum\limits_{x\in S}w_x)^p[合法]\) \(f(S)\ ... 
随机推荐
- LeetCode151:Reverse Words in a String
			题目: Given an input string, reverse the string word by word. For example, Given s = "the sk ... 
- 如何做好iOS应用安全?这有一把行之有效的“三板斧”
			本文由 网易云发布. iOS应用面临很多破解问题,常见的有IAP内购破解.山寨版本.破解版本等:大众应用上,微信抢红包.微信多开等:而在iOS游戏上,越来越泛滥的外挂问题也不断困扰着游戏厂商. 网易 ... 
- UCS2-little endian转码(utf16)
			public static void readFile(){ BufferedReader in = null; try { in = new BufferedReader(new InputStre ... 
- 内存耗用:VSS/RSS/PSS/USS
			Terms VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存) RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存) PSS - P ... 
- BZOJ 1003--[ZJOI2006]物流运输(最短路)
			1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10034 Solved: 4403 Description ... 
- (5)Oracle基础--约束
			· 约束的作用 <1> 定义规则 <2> 确保数据的完整性 · 约束 <1> 非空约束 ① 创建表时为字段添加非空约束 CREATE TABLE table_nam ... 
- 频繁项集挖掘之Aprior和FPGrowth算法
			频繁项集挖掘的应用多出现于购物篮分析,现介绍两种频繁项集的挖掘算法Aprior和FPGrowth,用以发现购物篮中出现频率较高的购物组合. 基础知识 项:“属性-值”对.比如啤酒2罐. 项集:项的集 ... 
- ubuntu14.04 安装五笔输入法(fcitx)
			ubuntu 14.04安装完成之后,一打字,默认的ibus一直在显示.解决办法,直接卸载ibus,使用fcitx. fictix拼音有fcitx-pinyin.fcitx-sogoupinyin.f ... 
- 杭电OJ之2020-2029(C语言版)
			2020. 绝对值排序 题目 Problem Description 输入n(n<=100)个整数,按照绝对值从大到小排序后输出.题目保证对于每一个测试实例,所有的数的绝对值都不相等. Inpu ... 
- 递归、字节流、文件复制_DAY20
			1:递归(理解) (1)方法定义中调用方法本身的现象. (2)递归注意事项: A:要有出口,否则就是死递归. B:次数不能太多,否则内存溢出. 特殊事项:构造方法不能递归定义. 例子:cn.itcas ... 
