数学


HDU 5901 素数个数,这题是完全拿别人的代码当作模板,忘记是谁的了,自己没重新实现,不贴代码



POJ 3233 矩阵快速幂+等比数列二分求和取模

#include <stdio.h>
#include <string.h>


const int MAXN = 35;
int n, k, m;

struct Matrix
{
	int g[MAXN][MAXN];

	void input()
	{
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				scanf("%d", &g[i][j]);
	}

	void output()
	{
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n - 1; j++)
				printf("%d ", g[i][j]);
			printf("%d\n", g[i][n - 1]);
		}
	}
};



Matrix operator*(const Matrix& x, const Matrix & y)
{
	Matrix temp;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			int sum = 0;
			for (int k = 0; k < n; k++)
			{
				sum = (sum + x.g[i][k] * y.g[k][j]) % m;
			}
			temp.g[i][j] = sum;
		}

	return temp;
}

Matrix operator+(const Matrix& x, const Matrix & y)
{
	Matrix temp;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			temp.g[i][j] = (x.g[i][j] + y.g[i][j]) % m;
	return temp;
}

Matrix operator^(const Matrix& x, int k)
{ //计算 A^k
	if (k == 0)
	{ //单位阵
		Matrix unit;
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				unit.g[i][j] = (i == j) ? 1 : 0;
		return unit;
	}
	if (k == 1)
		return x;
	Matrix temp = x ^ (k / 2); // temp = A^(k/2)
	if (k % 2)
		return temp*temp* x;//exp: A^7 = A^3 * A^3 * A;
	return temp* temp;
}

Matrix PowSumMod(Matrix x, int k)
{ //计算 s(k) = A + A^2 + A^3 + ... + A^k
	if (k == 1)
		return x;
	Matrix a = x ^ ((k + 1) / 2); // a = A^((k+1)/2)
	Matrix b = PowSumMod(x, k / 2); // b = s(k/2)
	if (k % 2 == 0)
		return ((x ^ 0) + a)* b; //exp: s(6) = (1 + A^3) * s(3)
	return x + ((x + a)* b); //exp: s(7) = A + (A + A^4) * s(3)
}

int main()
{
	while (scanf("%d%d%d", &n, &k, &m) == 3)
	{
		Matrix res;

		res.input();
		res = PowSumMod(res, k);

		res.output();
	}
	return 0;
}


POJ 2115 扩展欧几里得

#include<stdio.h>
using namespace std;

long long GcdEx(long long a, long long b, long long& x, long long& y)
{
	if (b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	long long d = GcdEx(b, a%b, x, y);
	long long xt = x;
	x = y;
	y = xt - a / b*y;
	return d;
}

int  main()
{
	long long  A, B, C, k;

	while (scanf("%lld%lld%lld%lld", &A, &B, &C, &k) == 4)
	{
		if (A == 0 && B == 0 && C == 0 && k == 0)
			return 0;

		long long a = C;
		long long c = (B - A);
		long long b = (long long)1 << k;//一定要先转成long long

		long long  x1, y1;
		long long  d = GcdEx(a, b, x1, y1);
		if (c % d != 0)
		{
			printf("FOREVER\n");
		}
		else
		{
			k = c / d;
			long long  ans = (k*x1) % b;
			long long  s = b / d;
			long long  minX = (ans%s + s) % s;
			printf("%lld\n", minX);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值