51nod 1583 犯罪计划——矩阵乘法优化dp
文泽想在埃及做案n次,并且想在最后不用得到惩罚。案件的被分成几种类型。比如说,案件A,当案件A被重复犯两次时,案件A将被认为不是犯罪案件,因此犯案人不用得到惩罚。也就是说,案件A被犯偶数次时,犯案人将不用得到惩罚。又比如案件B,当案件B被犯的次数是5的倍数时,犯案人将不用得到惩罚。
更具体的说,现在知道有c组条件。每组条件包含的信息如下:
1. 案件类型 ti ,
2. 底数 mi ,表示该类型案件重复n* mi (n是非负整数)次时,犯案人可以不用得到惩罚。
对于同一种案件,他的条件可能会被列出多个,在这种情况下,犯案人对该种案件犯罪次数至少满足其中一个条件就可以不受到惩罚。
文泽想要知道他犯n次罪后,并且不得到惩罚的犯罪情况的种数。
不得到惩罚的条件是,对于所有犯过n个案件的所有案件类型中,每种类型的案件都不用得到惩罚。
每个案件的犯罪顺序是有意义的。说明一下,现在有两种犯罪的案件序列W1和W2,如果对于所有的i(1≤i≤n)使得 W1i=W2i ,我们就认为这两个案件序列是一样的。
在样例中,有16种情况,分别为: AAAAA, AAABB, AABAB, AABBA, ABAAB, ABABA, ABBAA, BAAAB, BAABA, BABAA, BBAAA, ABBBB, BABBB, BBABB, BBBAB, BBBBA.
单组测试数据
第一行包含两个整数,n和c(0≤n≤10^18,0≤c≤1000),
分别表示文泽想要犯罪案件的个数和避免被惩罚的条件的组数。 接下来有c行。每行表示一组条件。
每组条件包含案件类型ti,和底数mi
这里ti一共有26种案件类型,分别用26个大写字母表示。
每个底数mi是一个正整数,所有mi的乘积不会超过123。
有些条件可能被重复列出多次。 如果某些案件类型没有在条件中被列出,那么文泽将不会考虑去犯这些类型的案件。
共一行,表示文泽犯n次罪后,并且不得到惩罚的犯罪情况的种数对12345取余。
5 2
A 1
B 2
16
(吐槽 对于一个刚开始学矩乘的人来说 这种题还是有点困难 存着以后加深理解
————————————————————————————————
这道题呢 因为所有mi的乘积不会超过123 所以本质不同的状态(S)只有<=123种
因为 对于每个有限制条件的字符,只需记录(它的出现次数)%(限制条件的mi之积)
枚举n以及状态 可以做到n*123^2吧
那就可以矩阵乘法做到123^3logn了(ccz原话
类似(f[i][S]表示考虑前i个字符,字符出现情况是S的方案数)
因为状态很少 我们可以预处理状态 然后离散化成整数
我直接用vector表示26维的状态 然后在离散化(利用map)
S有26维,dfs求出所有S,每个S直接用一个大小26的vector存,放进map离散化,枚举转移就行辣
具体不好讲 看看代码吧QAQ 不懂可以私我(我尽力
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define LL long long
using namespace std;
const int mod=;
LL read(){
LL ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
LL mx=,n,m;
char ch[];
int k,vis[],ed[][],h[][];
int b[][],c[][],d[][];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a/gcd(a,b)*b;}
vector<int>v1();
map<vector<int>,int>mmp;
int cnt;
void dfs(int k){
if(k==){mmp[v1]=cnt++; return;}
if(vis[k])for(int i=;i<vis[k];i++){v1[k]=i; dfs(k+);}
else{v1[k]=; dfs(k+);}
}
void pmod(int b[][],int c[][]){
for(int i=;i<mx;i++)
for(int j=;j<mx;j++) d[i][j]=;
for(int i=;i<mx;i++)
for(int k=;k<mx;k++)
for(int j=;j<mx;j++) (d[i][j]+=b[i][k]*c[k][j])%=mod;
for(int i=;i<mx;i++)
for(int j=;j<mx;j++) b[i][j]=d[i][j];
}
int main()
{
n=read(); m=read();
for(int i=;i<m;i++){
scanf("%s",ch); k=read();
vis[ch[]-'A']=;
ed[ch[]-'A'][k]=;
}
for(int i=;i<;i++) if(vis[i]){
for(int j=;j<;j++) if(ed[i][j]) vis[i]=lcm(vis[i],j);
mx*=vis[i];
for(int j=;j<;j++) if(ed[i][j]){
for(int k=;k<vis[i];k+=j) h[i][k]=;//左闭右开
}
}
dfs();//预处理出所有状态 map离散化
int v2;
for(map<vector<int>,int>::iterator it=mmp.begin();it!=mmp.end();it++){//处理状态之间的转移
v1=it->first; v2=it->second;
for(int i=;i<;++i)if(vis[i]){
v1[i]=(v1[i]+)%vis[i];
++c[mmp[v1]][v2];
v1[i]=(v1[i]-+vis[i])%vis[i];
}
}
for(int i=;i<mx;i++) b[i][i]=;
for(;n;n>>=,pmod(c,c)) if(n&) pmod(b,c);
int ans=;
for(map<vector<int>,int>::iterator it=mmp.begin();it!=mmp.end();it++){//枚举状态是否合法
bool f=false;
v1=it->first; v2=it->second;
for(int i=;i<;i++) if(vis[i]&&!h[i][v1[i]]) f=true;
if(!f) ans=(ans+b[v2][])%mod;
}
printf("%d\n",ans);
return ;
}
51nod 1583 犯罪计划——矩阵乘法优化dp的更多相关文章
- 形态形成场(矩阵乘法优化dp)
形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...
- 斐波那契数列 矩阵乘法优化DP
斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007\),\(n\le 10^{18}\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...
- [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】
题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...
- 矩阵乘法优化DP复习
前言 最近做毒瘤做多了--联赛难度的东西也该复习复习了. Warning:本文较长,难度分界线在"中场休息"部分,如果只想看普及难度的可以从第五部分直接到注意事项qwq 文中用(比 ...
- 矩阵乘法优化DP
本文讲一下一些基本的矩阵优化DP的方法技巧. 定义三个矩阵A,B,C,其中行和列分别为$m\times n,n \times p,m\times p$,(其中行是从上往下数的,列是从左往右数的) $C ...
- 【bzoj2476】战场的数目 矩阵乘法优化dp
题目描述 (战场定义为对于最高的一列向两边都严格不增的“用积木搭成”的图形) 输入 输入文件最多包含25组测试数据,每个数据仅包含一行,有一个整数p(1<=p<=109),表示战场的图形周 ...
- 【矩阵乘法优化dp】[Codeforces 621E] Wet Shark and Blocks
http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test 2 seconds ...
- luoguP2768: 珍珠项链(矩阵乘法优化DP)
题意:有K种珍珠,每种N颗,求长度为1~N的项链,包含K种珍珠的项链种类数.N<=1e9, K<=30; 思路:矩阵快速幂,加个1累加前缀和即可. #include<bits/std ...
- bzoj 4870: [Shoi2017]组合数问题 [矩阵乘法优化dp]
4870: [Shoi2017]组合数问题 题意:求 \[ \sum_{i=0}^{n-1} \binom{nk}{ik+r} \mod p \] \(n \le 10^9, 0\le r < ...
随机推荐
- javascript 运行机制 事件循环 浏览器缓存 (慕课网 前段跳槽面试必备 4-1,4-2,4-3)
4-1 渲染机制:-1-,什么是DOCTYPE及其作用?DTD(document type definition,文档类型定义)是一系列的语法规则,用来定义XML或(X)HTML的文件类型,浏览器会使 ...
- 一件安装lnmp
wget -c http://soft.vpser.net/lnmp/lnmp1.2-full.tar.gz && tar zxf lnmp1.2-full.tar.gz && ...
- ./vi: line 2: mkdir: command not found
当前两天博主在写脚本的时候,运行脚本时候总是出现此消息,很郁闷, 开始我以为可能是我mkdir的函数库依赖的问题,但是当我用其他的脚本创建 目录的时候,命令又可以用了,找了半天,终于找到了答案 --- ...
- 430. Flatten a Multilevel Doubly Linked List
/* // Definition for a Node. class Node { public: int val = NULL; Node* prev = NULL; Node* next = NU ...
- POJ:2566-Bound Found(尺取变形好题)
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5408 Accepted: 1735 Special J ...
- Java 的单元测试
有点需要注意,当 JUnit 主线程退出,子线程也会跟着退出,需要使用子线程的 join() 方法使主线程等待 Maven 依赖 <dependency> <groupId>j ...
- PHP.33-TP框架商城应用实例-后台9-商品相册-修改、删除(AJAX)
商品相册图片删除 当商品删除时,把相册中的图片一并从硬盘和数据库中删除,根据商品id[因为每一张商品相片都会生成三张缩略图,所以删除时要将其缩略图一并删除] //钩子方法_before_delete: ...
- ARabevaluator 颜色渐变控制类
参考资料: http://blog.csdn.net/qq_33456552/article/details/52092865 实现渐变效果: ArgbEvaluator argbEvaluator; ...
- border与background定位
1.background定位的局限 只能相对于左上角数值定位,不能相对于右下 即background-position默认相对于左上方定位的 2.怎样让图片相对于右下角? background-pos ...
- DJango跨域中间键
Skip to main content Search PyPISearch Help Donate Log in Register django-cors-middleware 1.3.1 pi ...