D. GukiZ and Binary Operations(矩阵+二进制)
D. GukiZ and Binary Operations
We all know that GukiZ often plays with arrays.
Now he is thinking about this problem: how many arrays a, of length n, with non-negative elements strictly less then 2l meet the following condition:
? Here operation
means bitwise AND (in Pascal it is equivalent to and, in C/C++/Java/Python it is equivalent to &), operation
means bitwise OR (in Pascal it is equivalent to
, inC/C++/Java/Python it is equivalent to |).
Because the answer can be quite large, calculate it modulo m. This time GukiZ hasn't come up with solution, and needs you to help him!
First and the only line of input contains four integers n, k, l, m (2 ≤ n ≤ 1018, 0 ≤ k ≤ 1018, 0 ≤ l ≤ 64, 1 ≤ m ≤ 109 + 7).
In the single line print the number of arrays satisfying the condition above modulo m.
2 1 2 10
3
2 1 1 3
1
3 3 2 10
9
In the first sample, satisfying arrays are {1, 1}, {3, 1}, {1, 3}.
In the second sample, only satisfying array is {1, 1}.
In the third sample, satisfying arrays are{0, 3, 3}, {1, 3, 2}, {1, 3, 3}, {2, 3, 1}, {2, 3, 3}, {3, 3, 0}, {3, 3, 1}, {3, 3, 2}, {3, 3, 3}.
,两两取与再取或的方式最后答案为k,问你有多少种方案数,答案取余m注意l=64的时候,要特别注意一下
我用了无符号的long long 各种错。。。最后还是long long 过的。
不知道是不是我编译器坏了。
转载请注明出处:
寻找&星空の孩子
题目链接:http://codeforces.com/contest/551/problem/D
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
using namespace std;//unsigned
struct matrix
{
LL mat[][];
};
LL mod; matrix multiply(matrix a,matrix b)
{
matrix c;
memset(c.mat,,sizeof(c.mat));
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
if(a.mat[i][j]==)continue;
for(int k=;k<;k++)
{
if(b.mat[j][k]==)continue;
c.mat[i][k]+=a.mat[i][j]*b.mat[j][k]%mod;
// c.mat[i][k]%=mod;
if(c.mat[i][k]>mod) c.mat[i][k]-=mod;
else if(c.mat[i][k]<) c.mat[i][k]+=mod;
}
}
}
return c;
} matrix quicklymod(matrix a,LL n)
{
matrix res;
memset(res.mat,,sizeof(res.mat));
for(int i=;i<;i++) res.mat[i][i]=;
while(n)
{
if(n&)
res=multiply(a,res);
a=multiply(a,a);
n>>=;
}
return res;
} LL ppow(LL a,LL b)
{
LL c=;
while(b)
{
if(b&) c=c*a%mod;
b>>=;
a=a*a%mod;
}
return c;
} int main()
{
LL n,k,l,m;
scanf("%I64d%I64d%I64d%I64d",&n,&k,&l,&mod);
if(l!=&&k>=(unsigned long long )(1ULL<<l)){printf("0\n");return ;}
matrix ans;
ans.mat[][]=;ans.mat[][]=;
ans.mat[][]=;ans.mat[][]=;
ans=quicklymod(ans,n);
//相邻没有连续两个1
LL x=(ans.mat[][]+ans.mat[][])%mod;
//至少有一个连续两个1
LL y=((ppow(,n)-x)%mod+mod)%mod;
// printf("x=%I64d\ty=%I64d\n",x,y);
LL sum=;
for(LL i=;i<l;i++)
{
if(k&(1LL<<i)) sum=(sum*y)%mod;
else sum=sum*x%mod;
}
printf("%I64d\n",sum%mod);
return ;
}
别人的 无符号过的。。。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef unsigned long long LL;
LL N,K,L,MOD;
struct Matrix
{
LL mat[][];
Matrix(){memset(mat,,sizeof(mat));}
Matrix operator*(Matrix A)
{
Matrix res;
for(int i=;i<;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
res.mat[i][j]=(res.mat[i][j]+mat[i][k]*A.mat[j][k]%MOD)%MOD;
return res;
}
};
LL pow_mul(LL x,LL n)
{
LL res=;
while(n)
{
if(n&)res=(res*x)%MOD;
x=(x*x)%MOD;
n>>=;
}
return res;
}
Matrix matrix_pow_mul(Matrix A,LL n)
{
Matrix res;
for(int i=;i<;i++)res.mat[i][i]=;
while(n)
{
if(n&)res=res*A;
A=A*A;
n>>=;
}
return res;
}
int main()
{
while(cin>>N>>K>>L>>MOD)
{
if(L!=&&K>=(1ULL<<L)){printf("0\n");continue;}
Matrix A,B;
A.mat[][]=A.mat[][]=A.mat[][]=;
A=matrix_pow_mul(A,N-);
B.mat[][]=;
B.mat[][]=;
A=A*B;
LL ans=;
LL sum=pow_mul(,N);
for(LL i=;i<L;i++)
{
if(K&(1LL<<i))ans=(ans*((sum-A.mat[][]+MOD)%MOD))%MOD;
else ans=(ans*A.mat[][])%MOD;
}
cout<<ans%MOD<<endl;
}
return ;
}
我用dp[i][j]表示有i个数,j表示最后一个数为0还是为1时满足没有相邻为1的方案数,因为n>=,所以i只有大于2才有意义。首先dp[][]=,dp[][]= , dp[][]=dp[][]+dp[][],dp[][]=dp[][] ………… 通项公式就是dp[n][]=dp[n-][]+dp[n-][],dp[n][]=dp[n-][] ,意思是当你长度为n最后一个数字为0时,你可以在长度为n-1最后一个数字为0或为1后面补0,这样不存在相邻为1的方案,若最后一位要为1,就只能在n-1最后一位为0的时候补1,这样才不会有相邻的1。最后你要计算的是all[n]=dp[n][]+dp[n][],其中dp[n][]==all[n-],dp[n][]==dp[n-][]==all[n-],推出all[n]=all[n-]+all[n-],这就是斐波那契数列。但这初始值有些不同,all[n] = fib[n+] ,fib第0个元素跟第1个元素为1. 算出不相邻的方案之后,只要算出总的方案数2^n(每一位取0或取1)减去不相邻的方案,即为相邻的方案。你也可以用dp去推一下,我稍微提一下,我用c[n]表示长度为n时具有相邻1的方案数,c[]= , c[]=c[]*+dp[][]………… c[n]=c[n-]*+dp[n-][]=c[n-]*+all[n-]这里的dp是上面求的不存在相邻的1,由于c[n-]具有相邻的1所以下一位任意,dp[n-][]是长度为n-1最后一位为1,我们补1让它有相邻的1.
得出是斐波那契数列之后,我们可以用矩阵快速幂求解斐波那契数,也可以用矩阵快速幂求c
注意:这道题wa点挺多的,首先是unsigned long long在判断是否越界的时候用,还有快速幂的次数是long long,枚举l位时候,第63位已经暴了10^,所以需要特判。最后输出结果要%mod,不然它有mod为1且l=0的样例
D. GukiZ and Binary Operations(矩阵+二进制)的更多相关文章
- Codeforces 551D GukiZ and Binary Operations(矩阵快速幂)
Problem D. GukiZ and Binary Operations Solution 一位一位考虑,就是求一个二进制序列有连续的1的种类数和没有连续的1的种类数. 没有连续的1的二进制序列的 ...
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations 矩阵快速幂优化dp
D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes inpu ...
- Codeforces 551 D. GukiZ and Binary Operations
\(>Codeforces \space 551 D. GukiZ and Binary Operations<\) 题目大意 :给出 \(n, \ k\) 求有多少个长度为 \(n\) ...
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations (矩阵高速幂)
题目地址:http://codeforces.com/contest/551/problem/D 分析下公式能够知道,相当于每一位上放0或者1使得最后成为0或者1.假设最后是0的话,那么全部相邻位一定 ...
- GukiZ and Binary Operations CodeForces - 551D (组合计数)
大意: 给定$n,k,l,m$, 求有多少个长度为$n$, 元素全部严格小于$2^l$, 且满足 的序列. 刚开始想着暴力枚举当前or和上一个数二进制中$1$的分布, 但这样状态数是$O(64^3)$ ...
- Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations
得到k二进制后,对每一位可取得的方法进行相乘即可,k的二进制形式每一位又分为2种0,1,0时,a数组必定要为一长为n的01串,且串中不出现连续的11,1时与前述情况是相反的. 且0时其方法总数为f(n ...
- uestc 1709 Binary Operations 位运算的灵活运用
Binary Operations Time Limit: 2000 ms Memory Limit: 65535 kB Solved: 56 Tried: 674 Description B ...
- 位运算 UEST 84 Binary Operations
题目传送门 题意:所有连续的子序列的三种位运算计算后的值的和的期望分别是多少 分析:因为所有连续子序列的组数有n * (n + 1) / 2种,所以要将他们分类降低复杂度,以ai为结尾的分成一组,至于 ...
- SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子
一起来学演化计算-SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子 觉得有用的话,欢迎一起讨论相互学习 ...
随机推荐
- 背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知
[源码下载] 背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知 作者:webabcd 介绍背水一战 Windows 1 ...
- Spring5中的DispatcherServlet初始化
Spring MVC像许多其它Web框架,被设计围绕前端控制器(DispatcherServlet)实际的工作是由可配置的,委托组件执行提供了一种用于请求处理的共享算法.这个模型是灵活的,支持不同的工 ...
- JSON Web Token(JWT)使用步骤说明
在JSON Web Token(JWT)原理和用法介绍中,我们了解了JSON Web Token的原理和用法的基本介绍.本文我们着重讲一下其使用的步骤: 一.JWT基本使用 Gradle下依赖 : c ...
- (爬虫向)python_json学习笔记
JSON学习笔记 - 在线工具 - https://www.sojson.com/ - http://www.w3school.com.cn/json/ - http://www.runoob.com ...
- PHP二维数组按照键值排序
在开发过程中,我们常常需要对二维数组按照数组的某个键来排序,这里提供两个封装好的方法,可以放到公共函数模块里以后需要的时候直接调用即可. /** * 二维数组按照键值降序排序 * @param arr ...
- Python 字符串增删改查的使用
#coding=utf-8a = 'haha'a = "hao"print(a)s = 'Hello World!'print(s.swapcase()) #大写变小写,小写变大写 ...
- Golang之发送消息至kafka
windows下安装zookeeper 1.安装JAVA-JDK,从oracle下载最新的SDK安装(我用的是1.8的) 2.安装zookeeper3.3.6,下载地址:http://apache.f ...
- 机器学习入门14 - 神经网络简介 (Introduction to Neural Networks)
原文链接:https://developers.google.com/machine-learning/crash-course/introduction-to-neural-networks/ 神经 ...
- 性能瓶颈之Mapping
如果Source和Target都不存在性能上的瓶颈,则问题可能会出在Mapping 如何判定Mapping存在性能瓶颈 1) 在session log中读取thread statistics和wor ...
- 阿里巴巴是如何打通 CMDB,实现就近访问的?
CMDB在企业中,一般用于存放与机器设备.应用.服务等相关的元数据.当企业的机器及应用达到一定规模后就需要这样一个系统来存储和管理它们的元数据.有一些广泛使用的属性,例如机器的IP.主机名.机房.应用 ...