SGU 476 Coach's Trouble 大数模拟

来源:互联网 发布:成都黑马程序员 编辑:程序博客网 时间:2024/05/17 22:32

题目链接:点击打开链接



#include <cstdio>#include <cstring>#include <map>using namespace std;typedef long long ll;const int len = 1000000000;const int L = 700;const int N = 3001;struct big {int a[L];void clear() {memset(a, 0, sizeof a);a[0] = 1;}void init() {memset(a, 0, sizeof a);a[0] = 698;a[698] = 1;}void out() {-- a[0];while (a[0] - 1 >= 1 && a[a[0]] == 0)-- a[0];printf("%d", a[a[0]]);for (int i = a[0] - 1; i >= 1; --i)printf("%09d", a[i]);puts("");}};void sub(big& x, big& y) {int v = 0, mx = x.a[0];if (mx < y.a[0]) mx = y.a[0];for (int i = 1; i <= mx; ++i) {x.a[i] += v;if (x.a[i] >= y.a[i]) {v = 0;x.a[i] -= y.a[i];} else {x.a[i] += len;v = -1;x.a[i] -= y.a[i];}}while (mx - 1 >= 1 && x.a[mx] == 0)-- mx;}void add(big& x, big& y) {ll v = 0;int mx = x.a[0];if (y.a[0] > mx) mx = y.a[0];for (int i = 1; i <= mx; ++i) {v += x.a[i] + y.a[i];x.a[i] = v % len;v /= len;}while (v > 0) {x.a[++mx] = v;v /= len;}x.a[0] = mx;}void multi(big& x, int y) {ll v = 0;int mx = x.a[0];for (int i = 1; i <= mx; ++i) {v = (ll)x.a[i] * y + v;x.a[i] = v % len;v /= len;}while (v > 0) {x.a[++mx] = v % len;v /= len;}x.a[0] = mx;}big d[N], ans;int wa[22][3], n, m, mx;int w[N];map<int, int> id;int cnt[N];void dfs(int idx, int g, int s) {if (g & 1) {-- cnt[n * 3 - g * 3];} else {++ cnt[n * 3 - g * 3];//add(ans, d[n * 3 - g * 3]);}if (idx >= 0) {int u, ret = s ^ mx, v = (1 << (idx + 1)) - 1;ret = ret & v;while (ret > 0) {u = id[ret & (ret - 1) ^ ret];if (u <= idx)dfs(u - 1, g + 1, s | w[u]);ret = ret& (ret - 1);}}}int main() {big vv;for (int i = 0; i < 20; ++i)id[1 << i] = i;d[0].clear();d[3].clear();d[0].a[1] = d[3].a[1] = 1;for (int i = 6; i <= 3000; i += 3) {d[i] = d[i - 3];multi(d[i], (i - 1) * (i - 2) / 2);}while (~scanf("%d%d", &n, &m)) {mx = (1 << m) - 1;for (int i = 0; i < m; ++i)scanf("%d%d%d", &wa[i][0], &wa[i][1], &wa[i][2]);memset(w, 0, sizeof w);for (int i = 0; i < m; ++i) {for (int j = i; j < m; ++j) {bool done = 1;for (int k = 0; done && k < 3; ++k)for (int l = 0; done && l < 3; ++l)if (wa[i][k] == wa[j][l]) {done = 0;w[i] |= 1 << j;w[j] |= 1 << i;}}}memset(cnt, 0, sizeof cnt);ans.init();dfs(m - 1, 0, 0);for (int i = 0; i < N; ++i)if (cnt[i] != 0) {if (cnt[i] > 0) {vv = d[i];multi(vv, cnt[i]);add(ans, vv);} else {vv = d[i];multi(vv, -cnt[i]);sub(ans, vv);}}ans.out();}return 0;}


0 0
原创粉丝点击