Codeforces Round#716(div.2)

Codeforces Round#716(div.2) (solved AB)

比赛链接 https://codeforces.com/contest/1514

C题

题目大意

给一个n,能否在数组[1,2,…,n-1]中找一个最长子序列,使序列乘积模n值为1

题解

第一、对n取模结果为1的数一定与n互质

选择的数只能是数组中与n互质的数,这样乘积才与n互质,那么先将数组中所有与n互质的数乘起来

第二、与n互质的数对n取模结果不一定为1

设乘积模n的结果为p,若p不为1,则从选择的数中将p移除

一句话就是“选择所有与n互质的数,乘积模n结果为p 若p不为1则从选择的数中移除p”

"p不为1时将p移除" 也就是说p一定落在了被选择的数中 为什么呢

数学地: a,b互质 a mod b 是否一定与b互质

证:

设c = a mod b

再设 b=md······① c=nd······② (d是b,c的一个公因数 m,n是各自的倍数)

下面若能证明d是a的因数,那么bc的公因数一定也是ab的公因数 而ab互质公因数为1 则bc公因数为1 则bc互质

c= a mod b 所以存在k使得 a=kb+c······③ 将①②带入③ a=kmd+nd=(km+n)d 即d是a的因数

结果不为1时,为什么将p移除 结果就为1了

数学地:小于n的所有质数乘积为s,p=s mod n 为什么当p不为1时 s/p mod n的结果一定为1

嗯…自己纠结了很久 然后发现其实是一个很明显的事情

s mod n=p 即 s除以n=k余p 由于s有因数p 那么k其实也是p的倍数 所以s/p=k/p余1 k/p是整数

(记得开long long)

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//	freopen("in.txt","r",stdin);
	int n;cin>>n;
	vector<int> ok(n+1);
	int p=1;
	int cnt=0;
	for(int i=1;i<n;i++){
		if(__gcd(i,n)==1){
			cnt++;
			p=p*i%n;
			ok[i]=1;
		}
	}
	if(p!=1){
		cnt--;
		ok[p]=0;
	}
	cout<<cnt<<'\n';
	for(int i=0;i<n;i++){
		if(ok[i])cout<<i<<' ';
	}
	#define _ 0
	return ~~(0^_^0);
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值