您的位置:首页 > 其它

【HDOJ】5564 Clarke and digits

2015-11-17 17:06 423 查看
DP+快速矩阵幂。注意base矩阵的初始化,不难。

/* 5564 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

const int mod = 1e9+7;
const int maxn = 75;
int ID[maxn][maxn];
int n;

typedef struct mat_t {
__int64 m[maxn][maxn];

mat_t() {
memset(m, 0, sizeof(m));
}

void init() {
memset(m, 0, sizeof(m));
}

void print() {
rep(i, 0, n) {
rep(j, 0, n) {
printf("%I64d ", m[i][j]);
}
putchar('\n');
}
}
} mat_t;

mat_t matMult(mat_t& a, mat_t& b) {
mat_t c;

rep(i, 0, n)
rep(j, 0, n)
rep(k, 0, n)
c.m[i][j] = (c.m[i][j] + a.m[i][k]*b.m[k][j]%mod)%mod;

return c;
}

mat_t matPow(mat_t a, int m) {
mat_t ret;

rep(i, 0, n)
ret.m[i][i] = 1;
while (m) {
if (m & 1)
ret = matMult(ret, a);
a = matMult(a, a);
m >>= 1;
}

return ret;
}

mat_t e;
mat_t base;

void init(int s) {
// first column is one
// first row is zero(accept first one)
rep(j, 0, n) {
e.m[0][j] = 0;
if (j%7 == 1)
e.m[j][0] = 1;
else
e.m[j][0] = 0;
}
e.m[0][0] = 1;

rep(i, 0, 10) {
rep(j, 0, 7) {
rep(ii, 0, 10) {
int jj = (10*j+ii)%7;
int id = ID[i][j];
int id_ = ID[ii][jj];
if (i+ii == s)
e.m[id][id_] = 0;
else
e.m[id][id_] = 1;
}
}
}

#ifndef ONLINE_JUDGE
// e.print();
#endif
}

void init_base() {
int cnt = 1;
n = 7*10+1;

rep(i, 0, 10)
rep(j, 0, 7)
ID[i][j] = cnt++;
rep(i, 1, 10)
base.m[0][ID[i][i%7]] = 1;
}

__int64 cal(int len) {
if (len == 0)
return 0;

__int64 ret = 0;
mat_t res = matPow(e, len);

rep(i, 0, n)
ret = (ret + base.m[0][i]*res.m[i][0]%mod)%mod;
return ret;
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t;
int l, r, s;
__int64 nl, nr, ans;

init_base();
scanf("%d", &t);
while (t--) {
scanf("%d %d %d", &l, &r, &s);
init(s);
nl = cal(l-1);
nr = cal(r);
ans = (nr-nl+mod) % mod;
#ifndef ONLINE_JUDGE
printf("nl = %I64d, nr = %I64d\n", nl, nr);
#endif
printf("%I64d\n", ans);
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: