`
he91_com
  • 浏览: 399406 次
文章分类
社区版块
存档分类
最新评论

HDU 3571 N-dimensional Sphere(高斯消元 数论题)

 
阅读更多

这道题算是比较综合的了,要用到扩展欧几里得,乘法二分,高斯消元。

看了题解才做出来orz

基本思路是这样,建一个n*(n-1)的行列式,然后高斯消元。

关键就是在建行列式时会暴long long,所以要用取模来计算,即公式ax=b,等价于ax=b(mod p)

因为答案范围不超过正负10^17次,p可以取(2*10^17+3)。

然后加减乘除都能够进行了,乘法用乘法二分来做,除法用模线性方程求逆来做。

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define LL __int64
const LL p=(LL)200000000*1000000000+3;//杭电的编译器不能直接写200000000000000003,会ce
const LL L=(LL)100000000*1000000000;
LL ans[60],a[60][60],h[60][60];
int n;
LL modans(LL s)//取模
{
	if(s<0)
		s=s+p;
	else if(s>=p)
		s=s-p;
	return s;
}
LL calcu(LL base,LL tmp)//乘法二分
{
    LL ans=0;
	while(tmp)
	{
		if(tmp&1)ans=modans(ans+base);
		base=modans(base*2);
		tmp/=2;
	}
	return ans;
}
void get_h(int s)//每一行初始化
{
	int i,j;
	LL tmp=0;
	for(i=0;i<n;i++)
	{
		h[s][i]=modans(2*(a[s][i]-a[s+1][i]));
		tmp+=calcu(a[s][i],a[s][i])-calcu(a[s+1][i],a[s+1][i]);
		tmp=modans(tmp);
	    //printf("%I64d ",h[s][i]);
	}
	h[s][n]=tmp;
	//printf("%I64d\n",h[s][n]);
}
void init()
{
	int i,j;
	for(i=0;i<n;i++)
		get_h(i);
}
LL extEculid(LL a,LL b,LL &x,LL &y)
{
	LL tmp,d;
	if(b==0){x=1;y=0;return a;}
	d=extEculid(b,a%b,x,y);
	tmp=x;x=y;y=tmp-a/b*y;
	return d;
}
void solve()
{
	int i,j,k;
	for(i=0;i<n;i++)//这一步不能落下,当第i行第i个数是0时,要与下面的行互换。这题数据貌似有点水,要是互换后第i个数还是0,就会出错了。。。
	{
		for(j=0;j<n;j++)
			if(h[i][j])
				break;
		if(i<j)
		{
			for(k=0;k<=n;k++)
				swap(h[i][k],h[j][k]);
		}
	}
	for(i=0;i<n-1;i++)
	{
	  
	  for(j=i+1;j<n;j++)
	  {
		int tmp=h[i][j];
		for(k=i+1;k<=n;k++)
			h[j][k]=modans(calcu(h[j][k],h[i][i])-calcu(h[i][k],h[j][i]));
	  }
	}
	LL x,y,g;
	for(i=n-1;i>=0;i--)
	{
		g=extEculid(h[i][i],p,x,y);//由于p是质数,所以g实际上等于1
		ans[i]=calcu(x,h[i][n]);
		for(j=0;j<i;j++)
			h[j][n]=modans(h[j][n]-calcu(h[j][i],ans[i]));
	}
}
int main()
{
	int t,i,j;
	scanf("%d",&t);
	for(int k=1;k<=t;k++)
	{
		scanf("%d",&n);
		for(i=0;i<=n;i++)
		for(j=0;j<n;j++)
		{
			scanf("%I64d",&a[i][j]);
			a[i][j]+=L;
		}
                init();
		solve();
		printf("Case %d:\n",k);
		printf("%I64d",(ans[0]-L)%L);
		for(i=1;i<n;i++)
          printf(" %I64d",(ans[i]-L)%L);
		printf("\n");
	}
	return 0;
}


分享到:
评论

相关推荐

    HDU-EID-V2-核心板1

    在本话题中,我们关注的是一个名为"HDU-EID-V2-核心板1"的特定设计,它涉及到STM32的核心组件、接口、电源管理和调试配置。 首先,核心板设计中提到了F103和F207两个型号的STM32芯片。F103和F207属于STM32的不同...

    HDU+2000-2099+解题报告

    HDU(杭州电子科技大学)在线评测系统是许多编程竞赛爱好者和学习者经常访问的平台,它提供了大量的算法题目供用户练习和挑战。这个压缩包文件“HDU 2000-2099 解题报告”显然包含了在这个题号范围内的一些问题、...

    hdu-OS-simple-shell,Linux_的_Shell_命令窗口_demo_版实现_shell-demo.zip

    hdu-OS-simple-shell,Linux_的_Shell_命令窗口_demo_版实现_shell-demo

    2019-hdu-multi-(2019杭电多校第二场数据与标程).zip

    《2019-hdu-multi-(2019杭电多校第二场数据与标程).zip》是一个专门针对编程竞赛爱好者和ACM(国际大学生程序设计竞赛)参赛者的资源包。这个压缩文件的核心内容是2019年杭州电子科技大学(HDU)主办的多校联合...

    HDU-2000-2099.zip_hdu2000

    【标题】"HDU-2000-2099.zip_hdu2000" 是一个包含杭电(Hangzhou Dianzi University)ACM竞赛题目解题报告的压缩包,覆盖了编号从2000到2099的题目。这个资源对于学习算法、提高编程技巧以及准备ACM/ICPC(国际大学...

    HDU-2000-2099.rar_hdu

    这个名为"HDU-2000-2099.rar_hdu"的压缩包包含了该平台从2000到2099共100道题目的源代码。这些题目涵盖了初级到高级的各种算法,对于学习和提升编程技能非常有帮助。 首先,我们来看看这些题目可能涉及到的基础知识...

    HDU+2000-2099+解题报告.zip

    《杭电OnlineJudge 2000-2099解题报告》是针对杭州电子科技大学(HDU)在线评测系统(OnlineJudge)中2000至2099题目的详细解答集锦,主要涵盖了算法分析、编程技巧以及问题解决策略等内容。这份解题报告以CHM...

    HDU-1535-.zip_多源点

    标题中的"HDU-1535-.zip_多源点"表明这是一个关于解决 ACM (国际大学生程序设计竞赛)问题的程序代码包,问题编号为 HDU 1535,且该问题涉及到多源点的最短路径计算。描述中提到的"求多源点到单终点的最短路(反向...

    HDU-EID-V2-扩展板1

    HDU-EID-V2-扩展板1是一款专为STM32微控制器设计的硬件扩展板,主要用于增强核心板的功能。该扩展板具有多种接口和功能,包括ADC(模数转换器)、电位器、DAC(数模转换器)输出以及TEST_V跳线,能够满足用户在模拟...

    hdu-page-11-answer.rar_hdu_hdu oj第十一页_page_搜题_杭电oj

    本资料"HDU Page 11 Answer"正是针对杭电OJ中第11页的题目,提供了一系列题解,旨在帮助初学者快速掌握基础算法,并提升编程能力。 一、ACM入门基础知识 ACM竞赛强调的是团队协作和快速解决问题的能力,其核心是...

    ACM HDU 2000-2099 解题报告 杭电 ACM

    《ACM HDU 2000-2099 解题报告 杭电 ACM》是一份详尽的编程竞赛解题集,主要涵盖了杭电(Hangzhou Dianzi University)在线判题系统(HDU OJ)上的2000至2099号题目。这份解题报告是针对参与ACM/ICPC(国际大学生...

    HDU-Coder-X#Daily-question-of-Leetcode#2022-04-04-307. 区域和检索 - 数

    其中一类查询要求 更新 数组 nums 下标对应的值另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和

    HDU-Coder-X#Daily-question-of-Leetcode#2021-12-12-709. 转换成小写字母1

    示例 1:示例 2:解答:大小写转换: n = n ^ 32转小写: n = n | 32转大写: n = n & -33const toLowerCase =

    HDU-Coder-X#Daily-question-of-Leetcode#2022-02-26-2016. 增量元素之间的最

    2016. 增量元素之间的最大差值题目描述:给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i]

    HDU-Coder-X#Daily-question-of-Leetcode#2021-09-24-430. 扁平化多级双向链表

    示例 1:输出:[1,2,3,7,8,11,12,9,10,4,5,6]输入的多级列表如下图所示:扁平化后的链表如下图:示例 2:输出:[1,3,2]解释:输入

    HDU-Coder-X#Daily-question-of-Leetcode#2022-01-15-1716. 计算力扣银行的钱

    示例 2:输入:n = 10输出:37解释:第 10 天后,总额为 (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4) = 37

    HDU ACMSteps-Chapter One-Section One答案集修正版

    杭州电子科技大学ACM Steps中Chapter One-Section One的答案集。不要直接抄哦~~ 如需题解请上我的博客~ 博客地址呈上:http://blog.csdn.net/xu_zh

Global site tag (gtag.js) - Google Analytics