题解 P5772 【[JSOI2016]位运算】
强烈推荐,戳此↓,看看我的博客
更好的阅读体验
题目大意
题目链接
给定两个整数
数据范围:
本题题解
假设我们已经知道了
因为
这个DP的时间复杂度是
发现上面的这个DP,没有用到“
那么关键就是要求出转移矩阵:
然后就对这个大小为
总时间复杂度
参考代码:
//problem:LOJ2075
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define lob lower_bound
#define upb upper_bound
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int MOD=1e9+7;
inline int mod1(int x){return x<MOD?x:x-MOD;}
inline int mod2(int x){return x<0?x+MOD:x;}
inline void add(int& x,int y){x=mod1(x+y);}
inline void sub(int& x,int y){x=mod2(x-y);}
inline int pow_mod(int x,int i){int y=1;while(i){if(i&1)y=(ll)y*x%MOD;x=(ll)x*x%MOD;i>>=1;}return y;}
const int MAXN=7,MAXK=1e5,MAXS=50;
const int SIZE2=1<<MAXN;
int n,K,len,bitcnt[SIZE2],dp[MAXS+5][SIZE2];
char s[MAXS+5];
struct Matrix{
int a[SIZE2][SIZE2],sz;
Matrix(){
memset(a,0,sizeof(a));
sz=0;
}
};
Matrix operator*(const Matrix& X,const Matrix& Y){
Matrix Z;
assert(X.sz==Y.sz);
Z.sz=X.sz;
for(int i=0;i<=X.sz;++i){
for(int j=0;j<=X.sz;++j){
for(int k=0;k<=X.sz;++k){
add(Z.a[i][j],(ll)X.a[i][k]*Y.a[k][j]%MOD);
}
}
}
return Z;
}
Matrix mat_pow(Matrix X,int i){
Matrix Y;
Y.sz=X.sz;
for(int j=0;j<=X.sz;++j)Y.a[j][j]=1;
while(i){
if(i&1)Y=Y*X;
X=X*X;
i>>=1;
}
return Y;
}
int main() {
cin>>n>>K;
cin>>(s+1);len=strlen(s+1);
int sz=(1<<n)-1;
for(int i=1;i<=sz;++i)bitcnt[i]=bitcnt[i>>1]+(i&1);
Matrix trans;
trans.sz=sz;
for(int st=0;st<=sz;++st){
memset(dp,0,sizeof(dp));
dp[0][st]=1;
for(int i=1;i<=len;++i){
for(int j=0;j<=sz;++j)if(dp[i-1][j]){
for(int k=0;k<=sz;++k)if(bitcnt[k]%2==0){
static int curs[MAXN+5];
curs[0]=s[i]-'0';
for(int l=1;l<=n;++l)curs[l]=((k>>(l-1))&1);
bool fail=false;
int newj=0;
for(int l=1;l<=n;++l){
if((j>>(l-1))&1){
//之前是等于的
if(curs[l]>curs[l-1]){fail=1;break;}
if(curs[l]==curs[l-1])newj|=(1<<(l-1));
}
}
if(fail)continue;
add(dp[i][newj],dp[i-1][j]);
}
}
}
for(int ed=0;ed<=sz;++ed){
trans.a[st][ed]=dp[len][ed];
}
}
trans=mat_pow(trans,K);
Matrix res;
res.a[0][sz]=1;
res.sz=sz;
res=res*trans;
cout<<res.a[0][0]<<endl;
return 0;
}