BZOJ 1172 Balkan2007 Dream
2016-07-01 17:38
169 查看
提示:
1. 一个乘积如果要判断整除 k ,我们需要记录哪些量
2. 每一行最多取两个可以单独抽出来做 dp
di 记录目前 gcd(乘积,k)==i 的方案数 , i 这个值的数量级是102级别的
那么我们就可以把相同 gcd 值的数归类,那么整体复杂度就降到了 106 级别。
1. 一个乘积如果要判断整除 k ,我们需要记录哪些量
2. 每一行最多取两个可以单独抽出来做 dp
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cassert> #include <cstdio> #include <vector> #include <cmath> #include <queue> #include <map> using namespace std; const int maxn = 210; int n , m , k , l , cnt; int d[maxn][maxn] , t[maxn] , now[maxn] , g[maxn][11000]; map<int , int> dic; int redic[maxn] , trans[maxn][maxn]; int main(int argc, char *argv[]) { cin>>n>>m>>k>>l; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d" , g[i] + j); for(int i=1;i<=k;i++) if(k % i == 0) redic[++cnt] = i , dic[i] = cnt; for(int i=1;i<=cnt;i++) for(int j=1;j<=cnt;j++) trans[i][j] = dic[__gcd((int)((1LL*redic[i]*redic[j])%k) , k)]; d[0][1] = 1; for(int i=1;i<=n;i++) { memset(t , 0 , sizeof t); for(int j=1;j<=m;j++) t[dic[__gcd(g[i][j] , k)]]++; memcpy(now , t , sizeof t); if(1 < i && i < n) { for(int j=1;j<=cnt;j++) for(int k=1;k<=cnt;k++) (now[trans[j][k]] += t[j]*t[k]) %= l; for(int j=1;j<=cnt;j++) (now[trans[j][j]] -= t[j]) %= l; } for(int j=1;j<=cnt;j++) for(int k=1;k<=cnt;k++) (d[i][trans[j][k]] += d[i-1][j]*now[k]) %= l; } cout<<(d [cnt]+l)%l<<endl; return 0; }
di 记录目前 gcd(乘积,k)==i 的方案数 , i 这个值的数量级是102级别的
那么我们就可以把相同 gcd 值的数归类,那么整体复杂度就降到了 106 级别。
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android dpi,dip,dp的概念以及屏幕适配
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题