 /**//*
n<=10^6个点,每个点有权值a[i]<=10^7 各不相同
若存在一个数x,使得a[i],a[j],x is a beautiful triple
即a^2 + b^2 = c^2 a,b,c互素
则i可以传播laugh到j
问最少需要需要让多少个顶点自行laugh,然后传播到全部的顶点

看了解题报告的
并查集做
但如何判断beautiful triple 两两判断O(n^2)会超时

有个性质:对于满足a^2 + b^2 = c^2的数,可用勾股数公式生成:
(x^2-y^2 , 2xy , x^2+y^2) x>y
该公式能生成所有的素勾股数(互质),需1奇1偶 ,且gcd(x,y) = 1
也能生出部分派生勾股数(如 6 8 10) , 2奇或2偶
由于a[i]<=MAX MAX= 10^7
所以必有x^2-y^2 <= MAX , 2xy <= MAX 但x^2+y^2不一定<= MAX
2y^2<=MAX
x^2<=MAX+y^2<=3MAX/2
=> x<=sqrt(3MAX/2) , y <= sqrt(MAX/2)
所以枚举x,y复杂度为O(MAX)
(注意x,y是1奇1偶且gcd(x,y) = 1)

参考watashi代码写的
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>

using namespace std;

const int MAX = 10000000;
const int MAXX = (int)(sqrt(1.5*MAX) + 0.5);
const int MAXN = 1000000;

 struct DisjointSet {
int fa[MAXN];
 void init(int n) {
 for(int i = 1 ; i <= n ; i++) {
fa[i] = i;
}
}
 int root(int x) {
return x == fa[x] ? x : fa[x] = root(fa[x]);
}
 bool join(int a ,int b) {
a = root(a);
b = root(b);
 if(a != b) {
fa[a] = b;
return true;
}
return false;
}
};

DisjointSet ds;
int id[MAX+10];

 inline int gcd(int x , int y) {
return y == 0 ? x : gcd(y , x % y);
}

 bool gao(int a , int b) {
return id[a] > 0 && id[b] > 0 && ds.join(id[a],id[b]);
}

int main()
  {
 for(int n ; ~scanf("%d",&n) ; ) {
fill(id,id+MAX+1,0);
ds.init(n);
 for(int i = 1,x; i <= n ; i++) {
scanf("%d",&x);
id[x] = i;
}
 for(int x = 1 ; x <= MAXX ; x++) {
 for(int y = x % 2 + 1 ; y < x ; y += 2) {
 if(gcd(x, y) == 1) {//need it 
int a = x*x - y*y;
int b = 2*x*y;
int c = x*x + y*y;
 if(a > MAX || b > MAX) {
continue;
}
n -= gao(a,b);
 if(c <= MAX) {
n -= gao(a,c);
n -= gao(b,c);
}
}
}
}
printf("%d\n",n);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|