#prim,gcd#UVA12716 GCD XOR&洛谷 1550 [USACO08OCT]Watering Hole G

UVA12716 GCD XOR

题目

\[\sum_{i=1}^{n}\sum_{j=i}^n[\gcd(i,j)==i\;xor\;j] \]


分析

首先来证明一下如果上式成立,那么\(i\;xor\;j=i-j(i>j)\)
\(i=j\)时必然不可能相等,钦定\(i>j\)
那么\(i\;xor\;j\geq i-j\),因为异或可以视为不退位的减法
并且\(\gcd(i,j)\leq i-j\),当\(i\)\(j\)互质时两式一定成立,
否则左右两边同时约掉最大公约数,那么依然成立(更相减损法也可以证明)
要想用\(i\;xor\;j=i-j\)证明\(gcd(i,j)=i\;xor\;j\)
就必须要满足\(gcd(i,j)=i-j\),因为更相减损法,所以\(gcd(i,i-j)=gcd(i,j)\)
所以必须要满足\(gcd(i,i-j)=i-j\)那说明\(i\)\(i-j\)的倍数,
那么枚举\(i-j\)和它的倍数\(i\),求出\(j\),然后用\(i\;xor\;j=i-j\)判断
由于\(i-(i-j)=j,i\;xor(i-j)\;=j\)所以可以直接用\(i\)\(i-j\)判断即可


代码

#include <cstdio>
#define rr register
using namespace std;
int ans,n;
signed main(){
	scanf("%d",&n);
	for (rr int i=1;i<=n;++i)
	for (rr int j=2;j*i<=n;++j)
	    ans+=((j*i)^i)==j*i-i;
	printf("%d",ans);
	return 0;
}

洛谷 1550 [USACO08OCT]Watering Hole G

题目


分析

考虑建一个超级源点与所有点相连边权为开凿水井的费用,
那就是一道裸的最小生成树,用prim解决就可以了


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=311;
int n,low[N],dis[N][N],ans,v[N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	n=iut()+1,low[0]=1e9;
	for (rr int i=2;i<=n;++i) dis[1][i]=dis[i][1]=iut();
	for (rr int i=2;i<=n;++i)
	for (rr int j=2;j<=n;++j) dis[i][j]=iut();
	for (rr int i=1;i<=n;++i) low[i]=dis[1][i]; v[1]=1;
	for (rr int i=1;i<n;++i){
		rr int k=0;
		for (rr int j=1;j<=n;++j)
		if (low[k]>low[j]&&!v[j]) k=j;
		ans+=low[k],v[k]=1;
		for (rr int j=1;j<=n;++j)
		if (low[j]>dis[k][j]&&!v[j])
		    low[j]=dis[k][j];
	}
	return !printf("%d",ans);
} 
posted @ 2020-08-11 16:01  lemondinosaur  阅读(83)  评论(0编辑  收藏  举报