这几天就顾着看以前的题,不写的码手还是会生疏啊
状态压缩+矩阵乘法
发现在长度为P的区间中符合题意的很有限,所以先压缩完建出图,用矩阵加速转移
为什么有状态压缩大家都要弄个DP上去呢,感觉只有压缩的部分没有DP呀。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<iostream> 6 #define inc(i,l,r) for(int i=l;i<=r;i++) 7 #define dec(i,l,r) for(int i=l;i>=r;i--) 8 #define mem(a) memset(a,0,sizeof(a)) 9 #define inf 30031 10 #define ll long long 11 #define succ(x) (1<<x) 12 #define lowbit(x) (x&(-x)) 13 #define NM 200 14 using namespace std; 15 int read(){ 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 19 return x*f; 20 } 21 int c[NM],n,m,p,cnt,ans; 22 struct mat{ 23 int a[NM][NM]; 24 }s,t; 25 mat operator*(const mat&x,const mat&y){ 26 mat s;mem(s.a); 27 inc(i,1,cnt)inc(j,1,cnt)inc(k,1,cnt) 28 (s.a[i][j]+=x.a[i][k]*y.a[k][j])%=inf; 29 return s; 30 } 31 void dfs(int x,int t,int num){ 32 if(x==p){ 33 if(num==m)c[++cnt]=t;return; 34 } 35 dfs(x+1,t<<1,num);dfs(x+1,t<<1|1,num+1); 36 } 37 void out(mat t){ 38 inc(i,1,cnt){ 39 inc(j,1,cnt)printf("%d ",t.a[i][j]);putchar('\n'); 40 }putchar('\n'); 41 } 42 int main(){ 43 freopen("data.in","r",stdin); 44 n=read();m=read();p=read(); 45 dfs(1,1,1); 46 inc(i,1,cnt)inc(j,1,cnt){ 47 int x=(c[i]<<1)^succ(p)^c[j]; 48 if(x==lowbit(x))t.a[i][j]=1; 49 } 50 // out(t); 51 inc(i,1,cnt)s.a[i][i]=1; 52 p=n-m; 53 for(mat V=t;p;p>>=1,V=V*V) 54 if(p&1)s=s*V; 55 // out(s); 56 printf("%d\n",s.a[cnt][cnt]); 57 return 0; 58 }