Crime Management CodeForces - 107D

Crime Management CodeForces - 107D
问题描述: Zeyad 想要在埃及犯下N项罪行并且不想受到惩罚。有若干种类的罪行。例如,行贿是一项罪行但是当行贿重复两次的时候就不被认为是犯罪。因此,行贿在犯偶数次的时候不被当做犯罪。超速是一项罪行,但是当重复的次数是五的倍数的时候就不被认为是犯罪。
  更特别的,现在已知有C个犯罪的条件。每个条件描述罪行的种类Ti和倍数Mi。如果Zeyad的犯Ti这罪名的次数是Mi的倍数,那么Zeyad就不会因此受到惩罚。有些罪名可能在条件中出现多次。那么只要满足至少一个条件Zeyad就不会受罚。当然如果Zeyad犯某种罪行的次数为0,他自然由于遵守法律而不会受罚。
  现在Zeyad想知道他有多少种犯罪方式使得他恰好犯下n次罪却不会受到任何惩罚。
  犯罪的顺序是有关系的。更正式的说,两个犯罪序列W1与W2被认为相同,当且仅当对于所有 1 ≤ i ≤ n,w1i = w2i成立。

输入格式:第一行有两个整数n,c 分别表示Zeyad想要犯罪的次数和他所知的条件的数目。紧接着是c个条件。共有26种罪名,分别用A-Z表示。每个条件包含一个大写字母表示罪名的类型和一个正整数表示倍数。所有条件中倍数的乘积不超过123。某些条件可以出现多次。当倍数是1时表示无论犯罪多少次都不会受到惩罚。显而易见,对于那些没有在条件中列出的罪名Zeyad不会考虑去犯它们因为这会不可避免地受到惩罚。

输出格式:输出一个非负整数,表示Zeyad恰好犯下n次罪却不会受到任何惩罚的犯罪方式数目模12345的值。

数据规模和约定: 0 ≤ n ≤ 1018, 0 ≤ c ≤ 1000

题解:此题最重要的一点是π(d)<=123。令p[i]为字母i所有d的乘积。p[i]<=123
f[i][a][b]…[z]:表示长度为i的字符串,‘A’个数 mod p[1] 等于a,‘B’个数 mod p[2] 等于b ……‘Z’个数 mod p[26] 等于z的情况总数。

因为π(d)<=123,所以每个n最多有123种状态。那么,把状态全部爆搜出来之后编号,就可以用一个123*123的矩阵来表示状态的转移。答案为矩阵的n次方。

坑点:n=0时一定有一种情况。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#define pb push_back
using namespace std;
typedef long long ll;
const int mod=12345;
const int N=1000+5;
const int L=123;
template <class T>
inline void getin(T&num){
    char c;bool flag=0;num=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值