[2018HN省队集训D8T3] 水果拼盘
[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] 水果拼盘的更多相关文章
- [2018HN省队集训D9T1] circle
[2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...
- [2018HN省队集训D8T1] 杀毒软件
[2018HN省队集训D8T1] 杀毒软件 题意 给定一个 \(m\) 个01串的字典以及一个长度为 \(n\) 的 01? 序列. 对这个序列进行 \(q\) 次操作, 修改某个位置的字符情况以及查 ...
- [2018HN省队集训D6T2] girls
[2018HN省队集训D6T2] girls 题意 给定一张 \(n\) 个点 \(m\) 条边的无向图, 求选三个不同结点并使它们两两不邻接的所有方案的权值和 \(\bmod 2^{64}\) 的值 ...
- [Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform
[Luogu P4143] 采集矿石 [2018HN省队集训D5T3] 望乡台platform 题意 给定一个小写字母构成的字符串, 每个字符有一个非负权值. 输出所有满足权值和等于这个子串在所有本质 ...
- [2018HN省队集训D5T2] party
[2018HN省队集训D5T2] party 题意 给定一棵 \(n\) 个点以 \(1\) 为根的有根树, 每个点有一个 \([1,m]\) 的权值. 有 \(q\) 个查询, 每次给定一个大小为 ...
- [2018HN省队集训D5T1] 沼泽地marshland
[2018HN省队集训D5T1] 沼泽地marshland 题意 给定一张 \(n\times n\) 的棋盘, 对于位置 \((x,y)\), 若 \(x+y\) 为奇数则可能有一个正权值. 你可以 ...
- [Codeforces 321D][2018HN省队集训D4T2] Ciel and Flipboard
[Codeforces 321D][2018HN省队集训D4T2] Ciel and Flipboard 题意 给定一个 \(n\times n\) 的矩阵 \(A\), (\(n\) 为奇数) , ...
- [2018HN省队集训D1T3] Or
[2018HN省队集训D1T3] Or 题意 给定 \(n\) 和 \(k\), 求长度为 \(n\) 的满足下列条件的数列的数量模 \(998244353\) 的值: 所有值在 \([1,2^k)\ ...
- [2018HN省队集训D1T1] Tree
[2018HN省队集训D1T1] Tree 题意 给定一棵带点权树, 要求支持下面三种操作: 1 root 将 root 设为根. 2 u v d 将以 \(\operatorname{LCA} (u ...
随机推荐
- linux下在线升级nodejs
因现有项目需要用一个截屏node包,此包必须新版本,所以紧急升级下测试环境nodejs,后续再升级线上,小小试了下node在线升级 方案1,使用npm安装n模块,使用n来升级nodejs 首先要知道n ...
- oracle 父子关系
语句递归查找父子关系语句 表结构及数据 1.通过根节点遍历子节点 select t.*,LEVEL from Test2 t START WITH t.parentid=0 CONNECT BY PR ...
- mongodb自学
http://www.runoob.com/mongodb/mongodb-databases-documents-collections.html
- NSLog演化
使用下面代码打印行号,功能函数,以及要打印的内容 #if DEBUG #define MBLog(format, ...) NSLog((@"%s--[Line:%d]--" fo ...
- 使用crontab调度任务
复杂的.分布式的.工作流式的调度可以通过azkaban来进行调度,除了执行调度任务之外,它还能进行定时调度.而对于简单的服务器任务,如执行一个小脚本,发送邮件等,可以使用crontab命令直接进行,在 ...
- 高并发第六弹:线程封闭(ThreadLocal)
当访问共享的可变数据时,通常需要使用同步.一种避免使用同步的方式就是不共享数据.如果仅在单线程内访问数据,就不需要同步.这种技术被称为线程封闭. 它其实就是把对象封装到一个线程里,只有一个线程能看到这 ...
- Java数据结构基础知识你知道多少?
http://www.cnblogs.com/qlky/p/7359462.html http://www.importnew.com/28263.html HashMap( java 7) 构造函数 ...
- 有趣:256个class选择器可以干掉1个id选择器——张鑫旭
我们应该都知道,从选择器得分权重上将,id选择器(#aaa{})和class选择器(.aaa{})完全不是一个数量级的,前者:1-0-0; 而后者为0-1-0.因此: #id { color:dark ...
- Code Signal_练习题_Minesweeper
In the popular Minesweeper game you have a board with some mines and those cells that don't contain ...
- BZOJ1597: [Usaco2008 Mar]土地购买(dp 斜率优化)
题意 题目链接 Sol 重新看了一遍斜率优化,感觉又有了一些新的认识. 首先把土地按照\((w, h)\)排序,用单调栈处理出每个位置第向左第一个比他大的位置,显然这中间的元素是没用的 设\(f[i] ...