【SRM20】数学场
第一题
n个m位二进制,求异或值域总和。
【题解】异或值域--->使用线性基,解决去重问题。
m位二进制--->拆位,每位根据01数量可以用组合数快速统计总和。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<bitset>
#include<algorithm>
#define ll long long
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=,MOD=1e9+; int n,m,fac[maxn],fav[maxn],f2[maxn],sum,ans;
char s[maxn];
bitset<maxn>a[maxn],b[maxn];
void gcd(int a,int b,int &x,int &y){
if(!b){x=;y=;}
else{gcd(b,a%b,y,x);y-=x*(a/b);}
}
int inv(int a){
int x,y;
gcd(a,MOD,x,y);
return ((x%MOD)+MOD)%MOD;
}
int C(int n,int m){return 1ll*fac[n]*fav[m]%MOD*fav[n-m]%MOD;}
int main(){
n=read();m=read();
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++)a[i][m-j]=s[j]-'';
for(int j=m-;j>=;j--)if(a[i][j]){
if(b[j]==){b[j]=a[i];break;}
else a[i]^=b[j];
}
}
int sum0,sum1;
fac[]=;for(int i=;i<=m;i++)fac[i]=1ll*fac[i-]*i%MOD;
for(int i=;i<=m;i++)fav[i]=inv(fac[i]);
f2[]=;for(int i=;i<=m;i++)f2[i]=1ll*f2[i-]*%MOD;
ans=;
for(int i=;i<m;i++){
sum0=sum1=sum=;
for(int j=;j<m;j++)if(b[j]!=){
if(b[j][i]==)sum0++;else sum1++;
for(int j=;j<=sum1;j+=)sum=(sum+C(sum1,j))%MOD;
ans=(ans+1ll*f2[i]*sum%MOD*f2[sum0]%MOD)%MOD;
}
printf("%d",ans);
return ;
}
第二题
给定n个数,求从中任意选数的所有方案gcd的总和。n个数字都<=m(给定)。n<=10^5,m<=10^6。
【题解】对于每个数字a(1<=a<=m)处理出n个数中有多少个是它的倍数,记为b,那么有它是2^b-1种方案的公因数,再容斥掉其倍数(ans[j])得到ans[i]。
使用的仍是自带容斥的技巧,就是直接容斥掉已经计算过的答案ans,这些答案ans已经自带上一层容斥了。
复杂度分析:1枚举n次,2枚举n/2次,所以总共枚举n*(1+1/2+1/3+1/4+...+1/n),后面的数列是常见的近似ln(n),所以总复杂度O(n ln n)。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=,MOD=1e9+; int n,m,f2[maxn],a[maxn],b[maxn],ans[maxn],ANS=;
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]),b[a[i]]++;
f2[]=;for(int i=;i<=m;i++)f2[i]=f2[i-]*%MOD;
for(int i=m;i>=;i--){
int num=;
for(int j=i;j<=m;j+=i)num+=b[j];
ans[i]=f2[num]-;
for(int j=i+i;j<=m;j+=i)ans[i]=(ans[i]+MOD-ans[j])%MOD;
ANS=(ANS+1ll*i*ans[i]%MOD)%MOD;
}
printf("%d",ANS);
return ;
}
第三题
给定n(n<=2000),1~n任意排列,进行如下操作:①若有序,停止。②发现连续一段+1,并在一起不再分开。③再次随机排列。
求停止前进行③的期望次数。
【题解】
期望问题直接考虑递推,f[i]表示1~i任意排列的期望次数,得到初步方程f[i]=1/i!*f[1]+?/i!*(f[j]+1),j表示剩余j块,?就是全排列中剩余j块的排列个数。
令a[i][j]表示1~i排列中共j块的排列数,得到方程f[i]=∑a[i][j]*(f[j]+1)/i!,j=2~i,把右边的f[i]移位后得f[i]=a[i][j]*(f[j]+1)/(i!-a[i][i])。(i=j时,f[j]暂时为0,就会+a[i][i])
接下来的问题是求a[i][j](j<i),因为一块就是连续一段,那么j块可以视为1~i(有序)的i-1个间隔中中放j-1个隔板,然后把隔出来的j段,视为j个数排列中形成j块的数量。
a[i][j]=a[j][j]*C(i-1,j-1),j<i
特别地,a[i][i]=i!-∑a[i][j],j=1~i-1。
过程中要记得,n个数排列形成n块的方案是a[n][n]而不是1,才不会出错!
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int abs(int x){return x>?x:-x;}
void mins(int &a,int b){if(a>b)a=b;}
void maxs(int &a,int b){if(a<b)a=b;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,MOD=1e9+,maxn=; void gcd(ll a,ll b,ll& d,ll& x,ll& y){
if(!b){d=a;x=;y=;}
else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
}
ll inv(ll a,ll n){
ll d,x,y;
gcd(a,n,d,x,y);
return (x%n+n)%n;
}
int n;
ll fac[maxn],fav[maxn],f[maxn],a[maxn][maxn];
ll C(ll n,ll m){return fac[n]*fav[m]%MOD*fav[n-m]%MOD;}
int main(){
fac[]=;fav[]=;
for(int i=;i<=;i++)fac[i]=fac[i-]*i%MOD;
for(int i=;i<=;i++)fav[i]=inv(fac[i],MOD);
n=read();
for(int i=;i<=n;i++){
a[i][i]=fac[i];
for(int j=;j<i;j++){
a[i][j]=C(i-,j-)*a[j][j]%MOD;
a[i][i]=(a[i][i]+MOD-a[i][j])%MOD;
}
}
f[]=;
for(int i=;i<=n;i++){
int o=;
for(int j=;j<=i;j++)o=(o+a[i][j]*(f[j]+))%MOD;//diao yong le ben shen
f[i]=o*inv((fac[i]+MOD-a[i][i])%MOD,MOD)%MOD;
}
printf("%lld",f[n]);
return ;
}
【SRM20】数学场的更多相关文章
- 【专题】计数问题(排列组合,容斥原理,Prufer序列)
[容斥原理] 对于统计指定排列方案数的问题,一个方案是空间中的一个元素. 定义集合x是满足排列中第x个数的限定条件的方案集合,设排列长度为S,则一共S个集合. 容斥原理的本质是考虑[集合交 或 集合交 ...
- XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
A. (a, b)-Tower 当指数大于模数的时候用欧拉定理递归计算,否则直接暴力计算. #include<cstdio> #include<algorithm> #incl ...
- Experimental Educational Round: VolBIT Formulas Blitz
cf的一次数学场... 递推 C 题意:长度<=n的数只含有7或8的个数 分析:每一位都有2种可能,累加不同长度的方案数就是总方案数 组合 G 题意:将5个苹果和3个梨放进n个不同的盒子里的方案 ...
- CF 445A 简单DP
今天早上找一道题的bug,还是找不出来,下午刷了几道水题,晚上准备回家的事, 然后本来想打CF的,一看,数学场,不打了. 这道题的题意: 给出一个序列,每次你可以从这个序列里面选择一个数ak,删除,然 ...
- 【题解】JSOIWC2019 Round4
题面: https://files-cdn.cnblogs.com/files/yzhang-rp-inf/P13.gif https://files-cdn.cnblogs.com/files/yz ...
- [noip2017] 前三周总结
[noip2017] 前三周总结 10.20 Fri. Day -21 距离noip复赛还有3周了,进行最后的冲刺! 首先要说今天过得并不好,和我早上比赛打挂了有关系. 不过每一次比赛都能暴露出我的漏 ...
- AtCoder Regular Contest 091
数学场,做到怀疑人生系列 C - Flip,Flip, and Flip...... Time limit : 2sec / Memory limit : 256MB Score : 300 poin ...
- Codeforces Round #524 (Div. 2)(前三题题解)
这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...
- [HDU6304][数学] Chiaki Sequence Revisited-杭电多校2018第一场G
[HDU6304][数学] Chiaki Sequence Revisited -杭电多校2018第一场G 题目描述 现在抛给你一个数列\(A\) \[ a_n=\begin{cases}1 & ...
随机推荐
- Spark Shuffle之Sort Shuffle
源文件放在github,随着理解的深入,不断更新,如有谬误之处,欢迎指正.原文链接https://github.com/jacksu/utils4s/blob/master/spark-knowled ...
- web.py 中文模版报错
1. 作为模板的html文件,必须是utf-8编码; 2. html文件内容中的charset必须为utf-8,也就是必须包含 <meta http-equiv="Content-Ty ...
- Js 中实现重定向的几种方式
之所以要总结这个,是因为在项目中使用了 AJAX,当请求成功时需要重定向到另一个页面. 1 . <script type="text/javascript"> wind ...
- postgis_LayerTransform
[转] postgis_LayerTransform 一个在postgis中结合中国国情,批量对数据进行加偏到百度坐标,高德谷歌的火星坐标,或者逆向纠偏 安装: 在postgresql-postgis ...
- PHP通过SMTP实现发送邮件_包括附件
require("class.phpmailer.php"); //这个是一个smtp的php文档,网上可以下载得到 $mail = new PHPMailer(); //建立邮件 ...
- (转)Redis使用详细教程
转载至http://www.cnblogs.com/wangyuyu/p/3786236.html 一.Redis基础部分: 1.redis介绍与安装比mysql快10倍以上 ************ ...
- [洛谷P4910]帕秋莉的手环
题目大意:有一个$n(n\leqslant10^{18})$个点的环,每个点可以是$0$或$1$,要求相邻点中至少一个$1$,问方案数,多组询问. 题解:先考虑是一条链的情况,令$f_{i,j}$表示 ...
- 【BZOJ1063】【NOI2008】道路设计(动态规划)
[BZOJ1063][NOI2008]道路设计(动态规划) 题面 BZOJ 题解 发现每个点最多只能被修一次等价于每个点最多只能和两条铁路相邻 考虑一个\(dp\) 设\(f[i][0/1/2]\)表 ...
- BZOJ1176:[Balkan2007]Mokia——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1176 Description(题面本人自行修改了一下) 维护一个W*W的矩阵,初始值均为0.每次操作 ...
- Redis的键值命令、服务器命令
Redis提供了丰富的命令对数据库和各种数据类型进行操作,这些命令可以在Linux 终端使用.在编程时,比如各类语言包,这些命令都有对应的方法. 键值命令 服务器命令 获取数据库中所有键名 >k ...