描述

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous.

Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 33 continuous hours when he eats only one kind of food, he will be unhappy. Besides, if there are 33 continuous hours when he eats all kinds of those, with chocolate at the middle hour, it will be dangerous. Moreover, if there are 33 continuous hours when he eats meat or fish at the middle hour, with chocolate at other two hours, it will also be dangerous.

Now, you are the doctor. Can you find out how many different kinds of diet that can make God Water happy and safe during NN hours? Two kinds of diet are considered the same if they share the same kind of food at the same hour. The answer may be very large, so you only need to give out the answer module 1000000007.

Input

The fist line puts an integer TT that shows the number of test cases. (T \le 1000T≤1000)

Each of the next TT lines contains an integer NN that shows the number of hours. (1 \le N \le 10^{10}1≤N≤1010)

Output

For each test case, output a single line containing the answer.

样例输入复制

3
3
4
15

样例输出复制

20
46
435170

题目来源

ACM-ICPC 2018 焦作赛区网络预赛

思路

有三种食物,肉 鱼 巧克力。

现在题目与有一些规定:

  1. 相同的食物连续吃三小时就会不高兴
  2. 在三个小时中,中间吃巧克力,另外的时间分别吃鱼和肉,他就会不高兴
  3. 在三个小时中,他第一个小时和第三个小时吃巧克力,其他时间吃其他的,他会不高兴

题目给出你他要吃多少个小时,问你使它高兴的方案数。

方法1:

那么我们可以想到POJ2778 DNA Sequence(AC自动机+矩阵快速幂)这个题,要求长度为n的序列中,不包含给的序列的方案数。我们用ac自动机+矩阵快速幂可以解决,那么思路就一样了,先把病毒串插入字典树,然后矩阵快速幂,记得加稀疏矩阵优化。

方法2:

暴力算出来前几项的值,然后用杜教BM线性递推板子。。(tql)

代码

方法1:

#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <sstream>
#include <cmath>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const ll N = 19;
const ll mod = 1e9 + 7;
struct Matrix
{ll mat[N][N], n;Matrix() {}Matrix(ll _n){n = _n;mem(mat, 0);}Matrix operator*(const Matrix &b) const{//printf("n=%lld\n", n);Matrix ret = Matrix(n);for (ll i = 0; i < n; i++)for (ll j = 0; j < n; j++)if (mat[i][j])for (ll k = 0; k < n; k++)ret.mat[i][k] = ret.mat[i][k] + mat[i][j] * b.mat[j][k] % mod;for (ll i = 0; i < n; i++)for (ll j = 0; j < n; j++)ret.mat[i][j] %= mod;return ret;}
};
Matrix mat_pow(Matrix a, ll n)
{Matrix ret = Matrix(a.n);for (ll i = 0; i < ret.n; i++)ret.mat[i][i] = 1;Matrix tmp = a;while (n){if (n & 1)ret = ret * tmp;tmp = tmp * tmp;n >>= 1;}return ret;
}
struct dicTree
{ll next[N][4], fail[N];bool end[N];ll root, sz;ll newnode(){for (ll i = 0; i < 3; i++)next[sz][i] = -1;end[sz++] = 0;return sz - 1;}void init(){sz = 0;root = newnode();}ll getch(char ch){if (ch == '1')return 0;if (ch == '2')return 1;if (ch == '3')return 2;}void insert(string s){ll len = s.size();ll now = root;for (ll i = 0; i < len; i++){ll to = getch(s[i]);if (next[now][to] == -1)next[now][to] = newnode();now = next[now][to];}end[now] = true;}void build(){queue<ll> q;fail[root] = root;for (ll i = 0; i < 3; i++){if (next[root][i] == -1)next[root][i] = root;else{fail[next[root][i]] = root;q.push(next[root][i]);}}while (!q.empty()){ll now = q.front();q.pop();if (end[fail[now]] == true)end[now] = true;for (ll i = 0; i < 3; i++){if (next[now][i] == -1)next[now][i] = next[fail[now]][i];else{fail[next[now][i]] = next[fail[now]][i];q.push(next[now][i]);}}}}Matrix get_mat(){Matrix res = Matrix(sz);for (ll i = 0; i < sz; i++)for (ll j = 0; j < 3; j++)if (end[next[i][j]] == false && end[i] == false)res.mat[i][next[i][j]]++;return res;}
};
dicTree ac;
int main()
{ll t, m;ac.init();string s[10];s[1] = "111";s[2] = "222";s[3] = "333";s[6] = "123";s[7] = "321";s[4] = "212";s[5] = "232";for (ll i = 1; i <= 7; i++){ac.insert(s[i]);}ac.build();Matrix a = ac.get_mat();scanf("%lld", &t);while (t--){scanf("%lld", &m);Matrix b = a;b = mat_pow(b, m);ll ans = 0;for (ll i = 0; i < ac.sz; i++)ans = ans + b.mat[0][i];printf("%lld\n", ans % mod);}return 0;
}

方法2:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long ll;
typedef vector<int> VI;
const int maxn = 10005;
const ll mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;ll fast_mod(ll a, ll n, ll Mod)
{ll ans = 1;a %= Mod;while (n){if (n & 1)ans = (ans * a) % Mod;a = (a * a) % Mod;n >>= 1;}return ans;
}namespace linear_seq
{ll res[maxn], base[maxn], num[maxn], md[maxn]; //数组大小约10000
vector<int> vec;
void mul(ll *a, ll *b, int k)
{for (int i = 0; i < 2 * k; i++)num[i] = 0;for (int i = 0; i < k; i++){if (a[i])for (int j = 0; j < k; j++)num[i + j] = (num[i + j] + a[i] * b[j]) % mod;}for (int i = 2 * k - 1; i >= k; i--){if (num[i])for (int j = 0; j < vec.size(); j++)num[i - k + vec[j]] = (num[i - k + vec[j]] - num[i] * md[vec[j]]) % mod;}for (int i = 0; i < k; i++)a[i] = num[i];
}
ll solve(ll n, VI a, VI b)
{ll ans = 0, cnt = 0;int k = a.size();assert(a.size() == b.size());for (int i = 0; i < k; i++)md[k - 1 - i] = -a[i];md[k] = 1;vec.clear();for (int i = 0; i < k; i++)if (md[i])vec.push_back(i);for (int i = 0; i < k; i++)res[i] = base[i] = 0;res[0] = 1;while ((1LL << cnt) <= n)cnt++;for (int p = cnt; p >= 0; p--){mul(res, res, k);if ((n >> p) & 1){for (int i = k - 1; i >= 0; i--)res[i + 1] = res[i];res[0] = 0;for (int j = 0; j < vec.size(); j++)res[vec[j]] = (res[vec[j]] - res[k] * md[vec[j]]) % mod;}}for (int i = 0; i < k; i++)ans = (ans + res[i] * b[i]) % mod;if (ans < 0)ans += mod;return ans;
}
VI BM(VI s)
{VI B(1, 1), C(1, 1);int L = 0, m = 1, b = 1;for (int i = 0; i < s.size(); i++){ll d = 0;for (int j = 0; j < L + 1; j++)d = (d + (ll)C[j] * s[i - j]) % mod;if (d == 0)m++;else if (2 * L <= i){VI T = C;ll c = mod - d * fast_mod(b, mod - 2, mod) % mod;while (C.size() < B.size() + m)C.push_back(0);for (int j = 0; j < B.size(); j++)C[j + m] = (C[j + m] + c * B[j]) % mod;L = i + 1 - L, B = T, b = d, m = 1;}else{ll c = mod - d * fast_mod(b, mod - 2, mod) % mod;while (C.size() < B.size() + m)C.push_back(0);for (int j = 0; j < B.size(); j++)C[j + m] = (C[j + m] + c * B[j]) % mod;m++;}}return C;
}
int gao(VI a, ll n)
{VI c = BM(a);c.erase(c.begin());for (int i = 0; i < c.size(); i++)c[i] = (mod - c[i]) % mod;return solve(n, c, VI(a.begin(), a.begin() + c.size()));
}
} // namespace linear_seqint main()
{//freopen("in.txt", "r", stdin);//填数字的时候带上模数之后的ll t, n;scanf("%d", &t);while (t--){scanf("%lld", &n);printf("%lld\n", linear_seq::gao(VI{3, 9, 20, 46, 106, 244, 560, 1286, 2956, 6794}, n-1));}return 0;
}

L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛,ac自动机+矩阵快速幂 或 BM线性递推)相关推荐

  1. ICPC 2018 焦作赛区网络预赛G Give Candies 组合数学隔板法+欧拉降幂

    G Give Candies 计蒜客 G Give Candies 题意 n n n个糖果, n n n个人从 1 1 1~ n n n编号,每次给一个人发糖可以发任意数量但不能小于 1 1 1,直到 ...

  2. ACM-ICPC 2018 焦作赛区网络预赛(A B E F G H I K L)

    ACM-ICPC 2018 焦作赛区网络预赛(A B E F G H I K L) 发了博客一万年之后才发现H1写错了(tao A. Magic Mirror 题目链接 题面: Jessie has ...

  3. ACM-ICPC 2018 焦作赛区网络预赛 J(二分+JAVA高精)

    传送门 题面: 65536K Jessie and Justin want to participate in e-sports. E-sports contain many games, but t ...

  4. ACM-ICPC 2018 焦作赛区网络预赛 H题 String and Times(SAM)

    Now you have a string consists of uppercase letters, two integers AA and BB. We call a substring won ...

  5. ACM-ICPC 2018 焦作赛区网络预赛 A. Magic Mirror (水)| B . Mathematical Curse(dp)

    A 题目: Jessie has a magic mirror. Every morning she will ask the mirror: 'Mirror mirror tell me, who ...

  6. ACM-ICPC 2018 南京赛区网络预赛 - AC Challenge(状压DP)

    ACM-ICPC 2018 南京赛区网络预赛 - AC Challenge 题意: 有n个题目,每个题目有一些信息,,第 t 个过第 i 题会得到分数 t*ai + bi 在过第 i 题前必须要先过  ...

  7. ACM-ICPC 2018 南京赛区网络预赛 AC Challenge

    Dlsj is competing in a contest with n (0 < n \le 20)n(0<n≤20) problems. And he knows the answe ...

  8. ACM-ICPC 2018 焦作赛区网络预赛 L Poor God Water(BM算法)

    题目链接:https://nanti.jisuanke.com/t/31721 题目大意:三种食物,n小时,连续三小时不能吃一样的东西,中间吃巧克力时连续三个小时吃的东西不能完全不同,如果中间吃鱼或者 ...

  9. ACM-ICPC 2018 焦作赛区网络预赛 L. Poor God Water

    #题解 大佬的递推式子..本弱鸡具体怎么得到的也不是很清楚 f(1)=3,f(2)=9,f(3)=20,f(4)=46,f(5)=106 f(n)=2f(n-1)-f(n-2)+3f(n-3)+2*f ...

最新文章

  1. rethat linux安装nginx,RedHat和CentOS下Nginx安装
  2. IF10+的数据库文章!这里有5个案例,一起发起来?
  3. delphi创建和读取xml(xml简单操作举例)
  4. android自定义尺子收集demo
  5. C# 单精度转换双精度丢失的问题
  6. TypeScript 枚举指南
  7. how does filter for list work in xml view
  8. 开发经验分享_03_解决问题3步走(思路)
  9. Centos7常用命令[挂载文件系统]
  10. 凿渠造舟:视频会议的昨天与明天
  11. 标准模板库(STL)之 priority_queue 列传
  12. C# winform窗体实现图片轮播
  13. python小代码_python小代码之阶乘求和
  14. LOLCC换肤盒子官网网站源码
  15. 聊聊Web 3为什么可以解决数据使用中存在的难题
  16. MessagingTimeout: Timed out waiting for a reply to message ID
  17. mindmanager2020官方下载永久激活版V20.1.237
  18. Python+pyecharts研究周杰伦歌词中的 秘密
  19. OPC客户端连接OPCserver报错或拒绝访问
  20. anthony1314的数论小基础

热门文章

  1. 如何设计一个地图功能,找到当前最近的加油站?
  2. AFNetworking官网文档及翻译
  3. 17joys项目配置
  4. EasyNVR实现海康、大华NVR硬盘录像机Web无插件播放方案(支持取特定时间段视频流)
  5. 浅谈德州扑克AI核心算法:CFR
  6. 素数求解的C语言方法
  7. 问题 D: DD_BOND看到的hcy
  8. 90后小伙用果酱画画:花鸟鱼虫活灵活现(图)
  9. swagger遇到的坑
  10. flutter Text文本,中英文混合,或则英文单词自动换行处理