hdu-3571:N-dimensional Sphere+高斯消元
2015-10-10 14:19
435 查看
copy别人的,做个标记,Orz..
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; typedef long long LL; const LL MOD = (LL)200000000 * 1000000000 + 3;/* 一个大于2*10^17的质数 */ const LL CORRECT = (LL)100000000 * 1000000000;/* 10^17 */ #define MAXN 50 LL broaden[MAXN][MAXN + 1]; /* 增广矩阵 */ LL ans[MAXN]; /* 用于保存答案 */ LL dataX[MAXN + 1][MAXN]; /* 原数据点 */ /* 计算a的模MOD值 */ LL getMod(LL a) { if (a < 0){ a += MOD; } else if (a >= MOD){ a -= MOD; } return a; } /* 二分方法计算a*b的值 */ LL multiMod(LL a, LL b) { LL ans = 0, base = a%MOD; while (b){ if (b & 1){ ans = getMod(base+ans); } base = getMod(base << 1); b >>= 1; } return ans; } /* 计算第i行的增广矩阵,即第i个式子 Σ[bn(i+1,j)^2-bn(i,j)^2]=2Σ[bn(i+1,j)-bn(i,j)]x(j) */ void calLineBroaden(int i, int n) { LL nb = 0; for (int j = 0; j < n; ++j){ broaden[i][j] = getMod((dataX[i + 1][j] - dataX[i][j]) << 1); nb += multiMod(dataX[i + 1][j], dataX[i + 1][j]) - multiMod(dataX[i][j], dataX[i][j]); nb = getMod(nb); } broaden[i] = nb; } /* 计算增广矩阵 */ void calBroaden(int n) { for (int i = 0; i < n; ++i){ calLineBroaden(i, n); } } /* 扩展欧几里德a*x+b*y=gcd(a,b) */ LL exGCD(LL a, LL b, LL&x, LL&y) { LL tmp, d; if (b == 0){ x = 1, y = 0; return a; } d = exGCD(b, a%b, x, y); tmp = x, x = y, y = tmp - a / b*y; return d; } /* 高斯消元,求解答案 */ void Gauss(int n) { int i, j; for (i = 0; i < n; ++i){ for (j = 0; j < n; ++j){ if (broaden[i][j])break; } if (i < j){ for (int k = 0; k <= n; ++k){ swap(broaden[i][k], broaden[j][k]); } } } for (i = 0; i < n - 1; ++i){ for (j = i + 1; j < n; ++j){ for (int k = i + 1; k <= n; ++k){ broaden[j][k] = getMod(multiMod(broaden[j][k], broaden[i][i]) - multiMod(broaden[i][k], broaden[j][i])); } } } LL x, y, g; for (i = n - 1; i >= 0; --i){ g = exGCD(broaden[i][i], MOD, x, y); ans[i] = multiMod(x, broaden[i] ); for (j = 0; j < i; ++j){ broaden[j] = getMod(broaden[j] - multiMod(broaden[j][i], ans[i])); } } } /* 打印结果 */ void printAns(int n) { for (int i = 0; i < n; ++i){ printf(i == 0 ? "%lld" : " %lld", (ans[i]-CORRECT)%CORRECT); } printf("\n"); } void gen() { int n; scanf("%d", &n); for (int i = 0; i <= n; ++i){ for (int j = 0; j < n; ++j){ scanf("%lld", &dataX[i][j]); dataX[i][j] += CORRECT; } } calBroaden(n); Gauss(n); printAns(n); } int main() { int t; scanf("%d", &t); for (int iCase = 1; iCase <= t; ++iCase){ printf("Case %d:\n", iCase); gen(); } return 0; }
相关文章推荐
- qq悬浮窗简单代码分享!
- pl/sql报错:Identifier is too long
- 基于Raphael.js的实现
- mysql修改密码
- C++11新特性
- tf-idf算法实现
- 也写mysql2redis安装
- Chapter 17 Replication
- win8.1 终于删除可恶的微软拼音
- 在楼市限购放开 你应该买房子还没有?
- LeetCode OJ:Combination Sum II (组合之和 II)
- [HDU 5441]Travel[并查集]
- jquery ajax传递关联数组
- linux文件属性
- log4j配置文件ssh整合(二)参考
- C语言 获得系统时间以及时间函数的用法。
- 一个小爬虫和正则表达式的例子,用于获取2015年迅雷校招的笔试名单
- URAL 1122 Game
- PASSION之logback(2)
- C++11 Features in Visual C++ 11