Cfz Round 3 Xor with Gcd

题目

这道题打暴力会超时

#include<iostream>
#include<algorithm>
using namespace std;
int sum;
void solve()
{
	int n;
	int f=0;
	int st=1;
	cin>>n;
	sum=0;
	sum=__gcd(st,n);
  // cout<<sum;
	int x=n;
	x--;
	while(x--)
	{  st=st+1;
		
	f=__gcd(st,n);
	//	cout<<"st"<<st<<"  ";
	//	cout<<sum<<"   ";
	///	
		sum=sum^f;
		//cout<<sum<<"  "<<f<<endl;
	}
	cout<<sum<<endl;
	
	return ;
}
int main()
{
	int t;
//	int q=0^3;
//	cout<<q;
	
	cin>>t;
	while(t--)solve();
	
	
	
	return 0;
}

所以不能暴力,明显有规律的,不过我找不到,看了题解才明白过来

再求最大公约数gcd的时候,
约定LCM[0,a]=0,GCD[0,a]=|a|,LCM[a,a]=|a|,GCD[a,a]=|a|
我们不妨将GCD称为最大公约数,将LCM称为最小非负公倍数。
还要就是求最大公约数的时候,有辗转相除法还要更相减损法,这道题目考了后者
gcd(a,b)=gcd(b-a,b)
对于^的操作有a^b^c=a^c^b交换律
还有就是a^a=0;
所以这道题我们发现gcd(i,n)=gcd(n-i,n),然后可以不断消 然后判断n偶数奇数即可了
n是偶数就n/2 n没消掉 这里注意了gcd(3,6)可不等于gcd(6,6),gcd(3,6)==gcd(6-3,6)

注意开long long

#include <iostream>
using namespace std;
void solve() {
	long long n;
	cin >> n;
	if (n % 2 == 1) {
		long long  g = 0 ^ n;
		cout << g << endl;
	} else {
		long long s = n / 2;
		long long y = s ^ n;
		cout << y << endl;
	}
	return ;
}
int main() {
	int t ;
	cin >> t;
	while (t--)solve();
	return 0;
}
posted @ 2025-04-16 20:26  LteShuai  阅读(13)  评论(0)    收藏  举报