玛里苟斯

一个大小为 \(n\) 的可重集合 \(a\) ,求 \(\mathbb E[x^k]\) ,其中 \(x\) 为 \(a\) 的一个子集的异或和。

\(n\le 10^5,1\le k\le 5\) ,保证答案小于 \(2^{63}\) 。

分析

这题挺妙的呢。

保证答案小于 \(2^{63}\) ,其实是告诉我们,答案的二进制位数 小于 64 位 。这就是说,对于一个 \(k\) ,\(a_i\) 的二进制位数 \(m\) 小于 \(\frac{64}{k}\) 。

首先明确这样一件事情:若 \(a\) 中某一位有 1,那么在所有异或和中,这一位为 1 的占 \(\frac{1}{2}\) 。也就是说,若这一位没有 1,那么所有异或和中这一位的期望为 0,否则为 \(\frac{1}{2}\) 。

这是因为,对于其他元素的所有子集的异或和,异或上这一位与不异或这一位,必定有一个 1 一个 0 ,所以 1 一定占刚好 \(\frac{1}{2}\) 。

令 \(S\) 为 \(n\) 的所有子集的异或和的可重集合,对每一位分开考虑,那就有

\[\begin{aligned}
\text{ans}&=\sum _{s\in S}(\sum_{i=0}^m 2^i[s_i=1])^k \\
&=\sum _{c_1=0}^m\sum _{c_2=0}^m\cdots\sum _{c_k=0}^m\frac{2^{\sum c}}{2^n}\sum _{s\in S}[s_{c_p}=1,p\in [1,k]] \\
&=\sum _{c_1=0}^m\sum _{c_2=0}^m\cdots\sum _{c_k=0}^m2^{\sum c}P(a中c_i位上均为1) \\
&=\sum _{c_1=0}^m\sum _{c_2=0}^m\cdots\sum _{c_k=0}^m2^{\sum c}\frac{[a中c_i位上均有1]}{2^{c_i中不同的个数}} \\
\end{aligned}
\]

最后的形式可以对 \(c\) 中的位建线性基来求。总复杂度为 \(O(m^{k+1}k)=O(64m^{k-1})\) 。

代码

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long giant;
inline char nchar() {
static const int bufl=1<<20;
static char buf[bufl],*a,*b;
return a==b && (b=(a=buf)+fread(buf,1,bufl,stdin),a==b)?EOF:*a++;
}
template<class T> inline T read() {
T x=0;
char c=nchar();
for (;!isdigit(c);c=nchar());
for (;isdigit(c);c=nchar()) x=x*10+c-'0';
return x;
}
const int maxn=1e5+1;
const int maxj=64;
const int maxk=5;
template<typename T> inline void Max(T &x,T y) {x=max(x,y);}
int b[maxk],c[maxk],n,m=0,k;
giant ans=0,a[maxj],s[maxn];
void dfs(int now) {
if (now==k) {
memset(b,0,sizeof b);
int gs=1;
for (int j=m;j>=0;--j) {
int x=0;
for (int i=k;i--;) if ((a[j]>>c[i])&1) x|=1<<i;
for (int i=k;i--;) if ((x>>i)&1) (b[i]?0:(b[i]=x,--gs)),x^=b[i];
}
int x=(1<<k)-1;
for (int i=k;i--;gs+=c[i]) if ((x^b[i])<x) x^=b[i];
if (!x) ans+=1ull<<gs;
return;
}
for (int i=0;i<=m;++i) c[now]=i,dfs(now+1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
n=read<int>(),k=read<int>();
for (int i=1,j;i<=n;++i) {
giant &x=s[i]=read<giant>();
for (j=maxj;j--;) if ((x>>j)&1) break;
Max(m,j);
}
for (int i=1;i<=n;++i) {
giant x=s[i];
for (int j=m;j>=0 && x;--j) if ((x>>j)&1) (a[j]?0:(a[j]=x)),x^=a[j];
}
dfs(0);
printf("%lld%s\n",ans>>1,ans&1?".5":"");
return 0;
}

主旋律

一个 \(n\) 个点 \(m\) 条边的有向图,问有多少种删边方案使得得到的有向图仍然是一个强连通图。\(n\le 15,m\le n(n-1)\) 。

分析

问题转化为有多少个点集不变的子图是强连通的。

复习一下强连通图计数,即可得到这题的方法——不过是在这个图上进行。

设 \(f(S)\) 为仅包含点集 \(S\) 的 强连通图 个数。

设 \(g(S)\) 为仅包含点集 \(S\) 的 多个(包括 1 个)强连通块组成的图个数,带容斥系数,奇数个连通块加,偶数个连通块减

设 \(h(S)\) 为仅包含点集 \(S\) 的有向图个数。

上述图的边都属于原图的边集。

有以下两条关系式:

\[\begin{aligned}
h(S)&=\sum _{\emptyset \subsetneqq T\subset S} g(T)h(S\setminus T)2^{b(T,S\setminus T)} \\
g(S)&=f(S)-\sum _{\emptyset \subsetneqq T\subsetneqq S} f(T)g(S\setminus T)
\end{aligned}
\]

其中 \(b(A,B)\) 表示 \(|\{(u,v)|,u\in A,v\in B,(u,v)\in E\}|\) 。

这可以用 in[x][s],out[x]][s] 分别表示 \(x\) 到一个集合的边数和集合到 \(x\) 的边数预处理。

预处理的部分会用到莫比乌斯变换,即子集之和。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long giant;
inline int read() {
int x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=15;
const int maxm=maxn*(maxn-1);
const int maxs=1<<maxn;
const int q=1e9+7;
inline int Plus(int x,int y) {return (x+=y)>=q?x-q:x;}
inline void Pe(int &x,int y) {x=Plus(x,y);}
inline int Multi(int x,int y) {return 1ll*x*y%q;}
inline void Me(int &x,int y) {x=Multi(x,y);}
inline int Sub(int x,int y) {return (x-=y)<0?x+q:x;}
inline void Se(int &x,int y) {x=Sub(x,y);}
inline int mi(int x,int y) {
int ret=1;
for (;y;y>>=1,Me(x,x)) if (y&1) Me(ret,x);
return ret;
}
int n,m,S,in[maxn][maxs],out[maxn][maxs],e[maxs],b[maxs],two[maxm+1];
int f[maxs],g[maxs],h[maxs];
struct bian {
int x,y;
} a[maxm];
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
two[0]=1;
for (int i=1;i<=maxm;++i) two[i]=Multi(two[i-1],2);
n=read(),m=read(),S=1<<n;
for (int i=0;i<m;++i) {
int &x=a[i].x=read()-1,&y=a[i].y=read()-1;
++in[y][1<<x],++out[x][1<<y],++e[(1<<x)|(1<<y)];
}
for (int i=0;i<n;++i) for (int j=0;j<n;++j) for (int s=0;s<S;++s) if ((s>>j)&1) Pe(in[i][s],in[i][s^(1<<j)]),Pe(out[i][s],out[i][s^(1<<j)]);
for (int i=0;i<n;++i) for (int s=0;s<S;++s) if ((s>>i)&1) Pe(e[s],e[s^(1<<i)]);
for (int s=1;s<S;++s) h[s]=two[e[s]];
for (int s=1;s<S;++s) { // rig?
for (int t=s;;t=(t-1)&s) {
int &bt=b[t]=0;
if (t==s) continue;
if (!t) break;
int o=s^t,x=__builtin_ctz(o);
bt=Plus(Sub(b[t^(1<<x)],out[x][o^(1<<x)]),in[x][t]);
}
int &gs=g[s]=h[s];
for (int t=s;t;t=(t-1)&s) Se(gs,Multi(Multi(g[t],h[s^t]),two[b[t]]));
}
for (int s=1;s<S;++s) {
int v=__builtin_ctz(s),&fs=f[s]=g[s];
for (int t=(s-1)&s;t;t=(t-1)&s) if ((t>>v)&1) Pe(fs,Multi(f[t],g[s^t]));
}
printf("%d\n",f[S-1]);
return 0;
}

奇数国

简单题,线段树+压位。

清华集训2015-Day 1的更多相关文章

  1. 清华集训2015 V

    #164. [清华集训2015]V http://uoj.ac/problem/164 统计 描述 提交 自定义测试 Picks博士观察完金星凌日后,设计了一个复杂的电阻器.为了简化题目,题目中的常数 ...

  2. 「清华集训2015」V

    「清华集训2015」V 题目大意: 你有一个序列,你需要支持区间加一个数并对 \(0\) 取 \(\max\),区间赋值,查询单点的值以及单点历史最大值. 解题思路: 观察发现,每一种修改操作都可以用 ...

  3. uoj164. 【清华集训2015】V 统计

    坑爹题面:http://uoj.ac/problem/164 正常题面: 对于一个序列支持下列5个操作: 1.区间加x 2.区间减x并与0取max 3.区间覆盖 4.单点查询 5.单点历史最大值查询 ...

  4. UOJ #164. 【清华集训2015】V | 线段树

    题目链接 UOJ #164 题解 首先,这道题有三种询问:区间加.区间减(减完对\(0\)取\(\max\)).区间修改. 可以用一种标记来表示--标记\((a, b)\)表示把原来的值加上\(a\) ...

  5. uoj#158. 【清华集训2015】静态仙人掌

    http://uoj.ac/problem/158 预处理dfs序,询问转为区间1的个数,用可持久化bitset预处理出所有可能的修改对应哪些位置,然后用一个bitset维护当前每个点的状态,修改时可 ...

  6. [清华集训2015 Day2]矩阵变换-[稳定婚姻模型]

    Description 给出一个N行M列的矩阵,保证满足以下性质: M>N. 矩阵中每个数都是 [0,N]中的自然数. 每行中, [1,N]中每个自然数刚好出现一次,其余的都是0. 每列中,[1 ...

  7. [清华集训2015 Day1]主旋律-[状压dp+容斥]

    Description Solution f[i]表示状态i所代表的点构成的强连通图方案数. g[i]表示状态i所代表的的点形成奇数个强连通图的方案数-偶数个强连通图的方案数. g是用来容斥的. 先用 ...

  8. [清华集训2015 Day1]玛里苟斯-[线性基]

    Description Solution 考虑k=1的情况.假设所有数中,第i位为1的数的个数为x,则最后所有的子集异或结果中,第i位为1的个数为$(C_{k}^{1}+C_{k}^{3}+...)$ ...

  9. LOJ 164 【清华集训2015】V——线段树维护历史最值

    题目:http://uoj.ac/problem/164 把操作改成形如 ( a,b ) 表示加上 a 之后对 b 取 max 的意思. 每个点维护当前的 a , b ,还有历史最大的 a , b 即 ...

  10. 2018.07.28 uoj#164. 【清华集训2015】V(线段树)

    传送门 线段树好题. 要求支持的操作: 1.区间变成max(xi−a,0)" role="presentation" style="position: rela ...

随机推荐

  1. 2018-2019-2 20175308实验一 《Java开发环境的熟悉》实验报告

    2018-2019-2-20175308 实验一 <Java开发环境的熟悉>实验报告 一.实验内容及步骤 (一)使用JDk编译.运行简单的Java程序 输入cd Code命令进入Code目 ...

  2. Spring 整合Mybatis实例

    演示样例下载地址:http://download.csdn.net/detail/geloin/4506640 本文基于Spring 注解,让Spring跑起来.本文使用Mysql数据库. (1) 导 ...

  3. [Lydsy1805月赛]口算训练 BZOJ5358

    分析: 没想到这道题还能二分查找... 这题主席树的话,裸的很显然...我们将每一个数分解质因数,之后建一个可持久化权值线段树维护[L,R]区间内的每一种质因子的个数,分解质因数的话,可以选择用线筛, ...

  4. Python3入门(十)——调试与测试

    一.异常处理 1.try...except...finally... 这个也就是Java里的try...cath..finally...了,直接看经典代码: try: print("开始执行 ...

  5. 一条insert语句插入数据库

    CREATE TABLE test_main ( id INT NOT NULL, value VARCHAR(10), PRIMARY KEY(id) ); oracle插入方式:INSERT IN ...

  6. 20155220 Exp5 MSF基础应用

    Exp5 MSF基础应用 一个主动攻击实践,MS08-067 首先利用msfconsole启用msf终端 然后利用search MS08-067搜索漏洞,会显示相应漏洞模块 根据上图,我们输入use ...

  7. 20155323刘威良《网络对抗》Exp6 信息搜集与漏洞扫描

    20155323刘威良<网络对抗>Exp6 信息搜集与漏洞扫描 实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查 ...

  8. 7、Class文件的格式

    Class文件的格式 1.magic(魔数) 身份标识,用来标记这是不是一个CLASS文件 CLASS的魔数比较有浪漫气息,是0xCAFEBABE(咖啡宝贝),也标识着将来JAVA咖啡商标: 2.之后 ...

  9. P4385 [COCI2009]Dvapravca

    首先特判掉蓝点数量\(<2\)的情况.没有蓝点答案就是\(n\),有一个蓝点可以枚举一个红点,选择过这个蓝点和红点的一条线和在无穷远处的平行线(即这条线对应的两个半平面). 这里认为过一个点是与 ...

  10. [arc102E]Stop. Otherwise...[容斥+二项式定理]

    题意 给你 \(n\) 个完全相同骰子,每个骰子有 \(k\) 个面,分别标有 \(1\) 到 \(k\) 的所有整数.对于\([2,2k]\) 中的每一个数 \(x\) 求出有多少种方案满足任意两个 ...