【美团杯2020】平行四边形 解题报告

本文是关于美团杯2020年竞赛中一道涉及原根的构造题目的解题报告。通过反证法证明了如何避免构成平行四边形,并提供了利用原根进行枚举的解决方案,时间复杂度为O(n)。
摘要由CSDN通过智能技术生成

原题地址:http://uoj.ac/problem/525

这是一道构造题,如果知道原根的话就容易想出来,不知道就很难做了。

题目n+1为质数以及1-n的排列已经暗示了要用原根(因为原根可以构造出一个排列,不会的可以去查查定义),那么怎么证明不会构成平行四边形呢?

使用反证法,考虑四个点(a,g^a),(b,g^b),(c,g^c),(d,g^d),不妨设a\leq b\leq c\leq d,若为平行四边形,则:

b-a=d-c,g^d-g^c=g^b-g^a

即:

g^c(g^{d-c}-1)=g^a(g^{b-a}-1)

由于b-a=d-c,g^{b-a}-1=g^{d-c}-1

g^c=g^a,a=c

即:a=c,b=d,不成立。

证毕。

那么只需要枚举找到原根,然后直接输出(i,g^i\operatorname{mod}(n+1))即可,时间复杂度为O(tn^2).

代码:

#include<cstdio>
using namespace std;
	int t,n;
int quickpower(int a,int b)
{
	int t = 1;
	while (b)
	{
		if (b & 1)
			t = t * a % (n + 1);
		a = a * a % (n + 1);
		b >>= 1;
	}
	return t;
}
int find(int m)
{
	for (int i = 2;i < m;i ++)
	{
		bool flag = false;
		for (int j = 1;j < m - 1;j ++)
			if (quickpower(i,j) == 1)
			{
				flag = true;
				break;
			}
		if (!flag)
			return i;
	}
}
int main()
{
	scanf("%d",&t);
	while (t --)
	{
		scanf("%d",&n);
		int g = find(n + 1);
		for (int i = 1;i <= n;i ++)
			printf("%d %d\n",i,quickpower(g,i));
	}
	return 0;
} 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值