您的位置:首页 > 其它

【BZOJ1002】【FJOI2007】轮状病毒

2018-01-12 11:10 260 查看
【题目链接】

点击打开链接

【思路要点】

输入与输出仅包含一个数,考虑找规律。
使用欧几里得算法配合\(Matrix-Tree\)定理求解取模一个大质数下问题的答案,并打表。
结果如下\(F(1)=1,F(2)=8,F(3)=16,F(4)=45,F(5)=121,F(6)=320,F(7)=841,F(8)=2205\)。
发现规律,\(F(i)=3*F(i-1)-F(i-2)+2(i≥5)\)。
递推即可,需要实现一个高精度类。
时间复杂度\(O(N*LogAns)\)。

【代码】

/*Program till Line 65*/
#include<bits/stdc++.h>
using namespace std;
#define MAXN	505
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
struct INT {int len, value[MAXN]; } a[MAXN];
INT operator + (INT a, INT b) {
INT res;
res.len = max(a.len, b.len);
memset(res.value, 0, sizeof(res.value));
for (int i = 0; i <= res.len; i++)
res.value[i] = a.value[i] + b.value[i];
for (int i = 0; i <= res.len; i++) {
res.value[i + 1] += res.value[i] / 10;
res.value[i] %= 10;
}
if (res.value[res.len + 1]) res.len++;
return res;
}
INT operator - (INT a, INT b) {
INT res;
res.len = a.len;
memset(res.value, 0, sizeof(res.value));
for (int i = 0; i <= res.len; i++)
res.value[i] = a.value[i] - b.value[i];
for (int i = 0; i <= res.len; i++)
if (res.value[i] < 0) {
res.value[i] += 10;
res.value[i + 1]--;
}
while (res.value[res.len] == 0) res.len--;
return res;
}
INT number(int x) {
INT res;
res.len = 0;
memset(res.value, 0, sizeof(res.value));
while (x) {
res.value[++res.len] = x % 10;
x /= 10;
}
return res;
}
void print(INT x) {
for (int i = x.len; i >= 1; i--)
printf("%d", x.value[i]);
printf("\n");
}
int main() {
int n; read(n);
a[1] = number(1);
a[2] = number(8);
a[3] = number(16);
a[4] = number(45);
for (int i = 5; i <= n; i++)
a[i] = a[i - 1] + a[i - 1] + a[i - 1] - a[i - 2] + number(2);
print(a
);
return 0;
}
/*Use the program below to print a form of answer*/
/*1 8 16 45 121 320 841 2205*/
#include<bits/stdc++.h>
using namespace std;
#define MAXN	505
#define P	1000000007
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
long long a[MAXN][MAXN];
long long calc(int n) {
int f = 1;
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++)
if (a[j][i]) {
if (i != j) {
swap(a[i], a[j]);
f = -f;
}
break;
}
if (a[i][i] == 0) return 0;
for (int j = 1; j <= n; j++) {
if (j == i || a[j][i] == 0) continue;
while (a[j][i]) {
swap(a[i], a[j]);
f = -f;
long long tmp = a[j][i] / a[i][i];
for (int k = 1; k <= n; k++)
a[j][k] = (a[j][k] - a[i][k] * tmp % P + P) % P;
}
}
}
long long ans = 1;
for (int i = 1; i <= n; i++)
ans = ans * a[i][i] % P;
if (f == 1) return ans;
else return (P - ans) % P;
}
int main() {
int n; read(n);
if (n == 1) {
printf("1\n");
return 0;
}
a[0][0] = n;
for (int i = 1; i <= n; i++) {
a[i][i] = 3;
a[0][i] = a[i][0] = P - 1;
}
for (int i = 1; i <= n - 1; i++)
a[i + 1][i] = a[i][i + 1] = P - 1;
a[1]
= a
[1] = P - 1;
printf("%lld\n", calc(n));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: