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)差分进化算子 觉得有用的话,欢迎一起讨论相互学习 ...
随机推荐
- day_6深浅拷贝,元组字典集合类型定义和各种操作方法
首先我们来讲一下深浅拷贝 1:值拷贝,假设一个列表等于L1 再定义一个L2=L1 这样就是值拷贝 L2只是存的L1存列表的地址,所以当L1发生改变,L2也随之改变 2:浅拷贝,L2=L1.copy( ...
- 解决jenkins控制台中文乱码问题
1,进入[系统管理]->[系统设置]->全局属性:KEY: LANG; VALUE:zh.CH.UTF-8 2,修改Jenkins.xml文件 在Jenkins安装目录下找到jenkins ...
- python爬虫学习之使用BeautifulSoup库爬取开奖网站信息-模块化
实例需求:运用python语言爬取http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html这个开奖网站所有的信息,并且保存为txt文件和excel文件. 实 ...
- Eclipse常用20个快捷键
Eclipse常用20个快捷键 1. Ctrl+F : 本文查找Find与替换Replace 2. Ctrl+H : 全局搜索,可按照文件类型搜索 3. Ctrl+1 : 快速修复,能快速的显示光标所 ...
- MySQL InnoDB 索引组织表 & 主键作用
InnoDB 索引组织表 一.索引组织表定义 在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT). 在Inno ...
- 第71节:Java中HTTP和Servlet
第71节:Java中HTTP和Servlet 前言 哭着也要看完!!!字数: 学习xml和TomCat 会写xml,看懂xml 解析对象 SAXReader reader = new SAXReade ...
- RISC-V平台的汇编指令解析
csrr a0, 0xF14 //把0xF14的值读入到a0中 andi a1, a0, 0x1f //把a0 和0x1F按位与运算后存储到a1中 srli a0, a0, 5 ...
- redux源码学习笔记 - applyMiddleware
在创建store时,createStore(reducer, preloadedState, enhancer),除了reducer函数,初始状态,还可以传入enhancer.这个enhancer在c ...
- es6入门3--箭头函数与形参等属性的拓展
对函数拓展兴趣更大一点,优先看,前面字符串后面再说,那些API居多,会使用能记住部分就好. 一.函数参数可以使用默认值 1.默认值生效条件 在变量的解构赋值就提到了,函数参数可以使用默认值了.正常我们 ...
- https://finance.sina.com.cn/realstock/company/sh600522/nc.shtml
https://finance.sina.com.cn/realstock/company/sh600522/nc.shtml http://hq.sinajs.cn/list=sh601006