题目大意:有一种长度为$n(n\leqslant 10^{18})$的字符串,给定$m(m\leqslant10^3)$种限制,即字符$c$出现的次数为$cnt$,若一个字符有多种限制,则满足任意一个即可,求这种字符串有多少个,所有的$cnt$相乘小于等于 123,答案对 12345 取模。

题解:最多$6$个限制的$cnt\not=2$,状态只需要记录这些不为$1$的限制,可以把每个限制出现次数压成一个数,构建矩阵,快速幂即可

卡点:

C++ Code:

#include <cstdio>
#include <vector>
#define maxn 1010
const int mod = 12345;
inline int min(int a, int b) {return a < b ? a : b;}
inline int max(int a, int b) {return a > b ? a : b;}
inline void up(int &a, int b) {if ((a += b) >= mod) a -= mod;}
inline long long pw(long long base, long long p) {
base %= mod;
long long res = 1;
for (; p; p >>= 1, base = base * base % mod) if (p & 1) res = res * base % mod;
return res;
} int __sz = 1;
struct matrix {
#define __M 150
#define M __sz
int s[__M][__M];
inline matrix() {
__builtin_memset(s, 0, sizeof s);
}
inline friend matrix operator * (const matrix &lhs, const matrix &rhs) {
matrix res;
for (register int i = 0; i < M; i++) {
for (register int j = 0; j < M; j++) {
long long tmp = 0;
for (register int k = 0; k < M; k++) tmp += static_cast<long long> (lhs.s[i][k]) * rhs.s[k][j];
res.s[i][j] = tmp % mod;
}
}
return res;
}
#undef __M
#undef M
} BASE, RES; long long n;
int m;
int mp[300], ret[300], __name, prod[300];
int base[300];
std::vector<int> v[300];
inline int get(int x, int i) {return x / base[i - 1] % prod[i];}
inline bool check(int x) {
for (int i = 1; i <= __name; i++) {
bool find = false;
int now = get(x, i);
for (std::vector<int>::iterator it = v[i].begin(); it != v[i].end(); it++) if (now % *it == 0) {
find = true;
break;
}
if (!find) return false;
}
return true;
} int main() {
scanf("%lld%d", &n, &m);
for (int i = 1, x, ch; i <= m; i++) {
char __ch;
scanf("%1s%d", &__ch, &x); ch = static_cast<int>(__ch);
if (!mp[ch]) mp[ch] = ++__name, ret[__name] = ch, prod[__name] = 1;
prod[mp[ch]] *= x;
v[mp[ch]].push_back(x);
__sz *= x;
}
base[0] = 1; for (int i = 1; i <= __name; i++) base[i] = base[i - 1] * prod[i];
for (int i = 0; i < __sz; i++) {
for (int j = 1; j <= __name; j++) {
int now = get(i, j), nxt = (now + 1) % prod[j];
up(BASE.s[i][i + (nxt - now) * base[j - 1]], 1);
}
}
RES.s[0][0] = 1;
for (; n; n >>= 1, BASE = BASE * BASE) if (n & 1) RES = RES * BASE;
int ans = 0;
for (int i = 0; i < __sz; i++) if (check(i)) up(ans, RES.s[0][i]);
printf("%d\n", ans);
return 0;
}

  

最新文章

  1. JavaScript获取当前日期,昨天,今天日期以及任意天数间隔日期
  2. NSOperationQueue的基本使用
  3. GET和POST请求
  4. Python:映像、集合
  5. [mock]7月25日
  6. React开发项目例子
  7. Peer to Peer File Sharing Through WCF
  8. Android开发_关于如何屏蔽Home键
  9. 第七十节,css选择器
  10. gulp源码解析(三)—— 任务管理
  11. zookeeper-3.4.5安装&amp;3台机器安装之后 ./zkServer.sh status 之后会显示“Error contacting service. It is probably not running.”的解决办法
  12. [UIKit学习]08.关于自定义控件
  13. 【bzoj2432】【NOI2011】兔农
  14. DensityUtil【尺寸转换工具类(px、dp互相转换)】
  15. codeforces131D
  16. Akka详细介绍
  17. Android studio preview界面无法预览,报错render problem
  18. mark 阿里支付
  19. Karma - MVC Framework for Unity3D
  20. [leetcode]151. Reverse Words in a String翻转给定字符串中的单词

热门文章

  1. nginx 只允许域名访问,禁止IP访问
  2. PHP中对字符串的一些操作
  3. ELK 分布式日志实战
  4. Hadoop参数调优
  5. python3 练习题100例 (二十三)与7相关的数
  6. 【JDBC】一、JDBC连接数据库
  7. centos配置npm全局安装
  8. python2.7入门---循环语句(for&amp;嵌套循环)
  9. 3106: [cqoi2013]棋盘游戏
  10. 4.HBASE数据迁移方案(之snapshot):