[2018HN省队集训D8T3] 水果拼盘

题意

给定 \(n\) 个集合, 每个集合包含 \([1,m]\) 中的一些整数, 在这些集合中随机选取 \(k\) 个集合, 求这 \(k\) 个集合的并集的权值的期望.

一个集合的权值定义为, 对于所有 \([1,m]\) 的整数, 若集合中含有 \(i\) 则产生 \(a_i\) 的贡献, 否则产生 \(b_i\) 的贡献.

\(n\le 1\times 10^5, m\le 18,k\le 25\)

题解

好像只有我一个写了一些玄学FWT操作...别人都是组合数直接碾的qaq

显然我们可以通过求所有最终集合的生成概率来计算出最终期望. 而这个概率显然就是个或卷积的形式.

于是我们可以FWT一发.

接着我们发现直接FWT卷 \(k\) 次可能会有重复的方案. (就像[BZOJ 3771] Triple那题). 于是我们需要考虑容斥.

然而这次是广义容斥, 普通二项式反演出来是假的.

stdcall&栋栋说过广义容斥瞎换一波系数就过了, 于是思考一些奇怪的东西来凑容斥系数.

FWT卷 \(k\) 次后得到的方案数是 \(n^k\), 而我们实际上需要的不重复的方案数应该是 \(n^{\underline k}\) (卷积出来的方案有序, 要自带一个全排列), 那么我们需要用一些玄学系数用 \(n^k\) 凑出 \(n^{\underline k}\).

注意到其实 \(n^{\underline k}\) 就是一个普通多项式, 那么我们可以直接算出这个多项式的每一项系数把它作为容斥系数.

实际上就是带符号第一类斯特林数. 用这个系数容斥一下就好了.

FWT一次后的点值可以重复使用, 所以总时间复杂度是 \(O(\sum|S|+(k+m)2^m)\).

参考代码

#include <bits/stdc++.h>

const int MAXK=27;
const int MAXL=1e6+10;
const int MOD=998244353; int n;
int m;
int k;
int a[MAXL];
int pw[MAXK];
int ans[MAXL];
int cof[MAXK];
int c[MAXK][2]; void FWT(int*,int);
void IFWT(int*,int);
inline int ReadInt();
inline int Pow(int,int,int); int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<m;i++)
scanf("%d",c[i]+1);
for(int i=0;i<m;i++)
scanf("%d",c[i]);
cof[0]=1;
for(int i=0;i<k;i++){
for(int j=i+1;j>0;j--)
cof[j]=(cof[j-1]-1ll*cof[j]*i%MOD+MOD)%MOD;
cof[0]=(MOD-1ll*cof[0]*i%MOD)%MOD;
}
for(int i=0;i<n;i++){
int cnt=ReadInt(),s=0;
while(cnt--)
s|=(1<<(ReadInt()-1));
++a[s];
}
int maxs=1<<m;
FWT(a,maxs);
pw[0]=1;
for(int s=0;s<maxs;s++){
for(int i=1;i<=k;i++)
pw[i]=1ll*pw[i-1]*a[s]%MOD;
for(int i=0;i<k;i++)
ans[s]=(ans[s]+1ll*pw[k-i]*cof[k-i])%MOD;
}
IFWT(ans,maxs);
int cnt=0;
int sum=0;
for(int s=0;s<maxs;s++){
(cnt+=ans[s])%=MOD;
for(int i=0;i<m;i++)
sum=(sum+1ll*c[i][(s>>i)&1]*ans[s])%MOD;
}
printf("%lld\n",1ll*sum*Pow(cnt,MOD-2,MOD)%MOD);
return 0;
} inline void FWT(int* a,int len){
for(int i=1;i<len;i<<=1)
for(int j=0;j<len;j+=(i<<1))
for(int k=0;k<i;k++){
a[j+k+i]+=a[j+k];
a[j+k+i]=(a[j+k+i]>=MOD?a[j+k+i]-MOD:a[j+k+i]);
}
} inline void IFWT(int* a,int len){
for(int i=1;i<len;i<<=1)
for(int j=0;j<len;j+=(i<<1))
for(int k=0;k<i;k++){
a[j+k+i]-=a[j+k];
a[j+k+i]=(a[j+k+i]<0?a[j+k+i]+MOD:a[j+k+i]);
}
} inline int ReadInt(){
int x=0;
register char ch=getchar();
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch)){
x=x*10+ch-'0';
ch=getchar();
}
return x;
} inline int Pow(int a,int n,int p){
int ans=1;
while(n>0){
if(n&1)
ans=1ll*a*ans%p;
a=1ll*a*a%p;
n>>=1;
}
return ans;
}

[2018HN省队集训D8T3] 水果拼盘的更多相关文章

  1. [2018HN省队集训D9T1] circle

    [2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...

  2. [2018HN省队集训D8T1] 杀毒软件

    [2018HN省队集训D8T1] 杀毒软件 题意 给定一个 \(m\) 个01串的字典以及一个长度为 \(n\) 的 01? 序列. 对这个序列进行 \(q\) 次操作, 修改某个位置的字符情况以及查 ...

  3. [2018HN省队集训D6T2] girls

    [2018HN省队集训D6T2] girls 题意 给定一张 \(n\) 个点 \(m\) 条边的无向图, 求选三个不同结点并使它们两两不邻接的所有方案的权值和 \(\bmod 2^{64}\) 的值 ...

  4. [Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform

    [Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform 题意 给定一个小写字母构成的字符串, 每个字符有一个非负权值. 输出所有满足权值和等于这个子串在所有本质 ...

  5. [2018HN省队集训D5T2] party

    [2018HN省队集训D5T2] party 题意 给定一棵 \(n\) 个点以 \(1\) 为根的有根树, 每个点有一个 \([1,m]\) 的权值. 有 \(q\) 个查询, 每次给定一个大小为 ...

  6. [2018HN省队集训D5T1] 沼泽地marshland

    [2018HN省队集训D5T1] 沼泽地marshland 题意 给定一张 \(n\times n\) 的棋盘, 对于位置 \((x,y)\), 若 \(x+y\) 为奇数则可能有一个正权值. 你可以 ...

  7. [Codeforces 321D][2018HN省队集训D4T2] Ciel and Flipboard

    [Codeforces 321D][2018HN省队集训D4T2] Ciel and Flipboard 题意 给定一个 \(n\times n\) 的矩阵 \(A\), (\(n\) 为奇数) , ...

  8. [2018HN省队集训D1T3] Or

    [2018HN省队集训D1T3] Or 题意 给定 \(n\) 和 \(k\), 求长度为 \(n\) 的满足下列条件的数列的数量模 \(998244353\) 的值: 所有值在 \([1,2^k)\ ...

  9. [2018HN省队集训D1T1] Tree

    [2018HN省队集训D1T1] Tree 题意 给定一棵带点权树, 要求支持下面三种操作: 1 root 将 root 设为根. 2 u v d 将以 \(\operatorname{LCA} (u ...

随机推荐

  1. Wordpress性能优化:使用crontab+wp-cli代替wp-cron

    wp-cron的问题     Wordpress内置wp-cron的模块,可以用来执行定时任务,比如定时检查更新,定时发布文章等都需要用到,属于必备功能.但是该模块的特点是:它只能在用户发起请求时检查 ...

  2. git 入门学习

    1. 分享一个我自己的百度网盘地址 链接:https://pan.baidu.com/s/17W7gpJNbqgBFy7VOl6-dvw 提取码:2a7t 2.安装就不说了,基本全默认就OK.安装完城 ...

  3. JAVA编写简单的日历,输入日期即可查看日历

    利用LocalDate输入年月日找出当月日历 直接上代码 import java.time.LocalDate; import java.util.Scanner; public class Cale ...

  4. Linux线程同步——条件变量

    互斥锁是用来给资源上锁的,而条件变量是用来等待而不是用来上锁的. 条件变量用来自动阻塞一个线程,直到某特殊情况发生为止. 通常条件变量和互斥锁同时使用. 和条件变量使用有关的几个重要函数: int p ...

  5. jquery 对象的 height、innerHeight、outerHeight 的区别以及DOM 元素的 clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop

    前言:jquery 对象的 height.innerHeight.outerHeight,还有 DOM 元素的 clientHeight.offsetHeight.scrollHeight.offse ...

  6. 使用JavaScript动态更改CSS样式

    在很多情况下,都需要对网页上元素的样式进行动态的修改.在JavaScript中提供几种方式动态的修改样式,下面将介绍方法的使用.效果.以及缺陷. 1.使用obj.className来修改样式表的类名. ...

  7. 关于redux

    react将dom解耦,不用直接操作dom,使用了状态机制,当状态改变时视图就会相应更新.我们知道在react中,父组件可以将一些状态传递给子组件,让子组件的视图相应更新,这时我们会发现,只有有关联的 ...

  8. 地图的可视化--Folium

    1.安装folium pip install MarkupSafe-0.23-cp34-none-win_amd64.whl pip install Jinja2-2.8-py2.py3-none-a ...

  9. Keras vs. PyTorch in Transfer Learning

    We perform image classification, one of the computer vision tasks deep learning shines at. As traini ...

  10. 那些年vue踩过的坑

    1.前言 学习Vue前端框架已经一个月了,作为一个web刚入门的菜鸟,在学习的过程中,网上有些技术博客往往没有什么可以借鉴的地方,在这里 我特意将我从开始一直到登录的过程记录下来.希望看到我的文章的朋 ...