题目链接:http://codeforces.com/problemset/problem/60/D
大意:N个不相同的数,如果对两个数a,b 存在一个c,使得这三个数的一种排列满足:x^2+y^2=z^2,并且a,b,c两两互质,那么a,b之间可以连一条边。问有多少个连通块。
(自己想问题的时候,注意力不能好好集中呀。。做了很多重复的思考。
读题也没抓住重点,漏看了一些条件
)
分析: 显然这道题目从x^2+y^2=z^2入手,记得初中遇到过这个表达式,问是否有整数解。 化成: x^2 = (z-y)*(z+y);
(1) 看到这个的是时候,第一想法就是将x分解成两个数,从而得到 z-y,z+y,计算得到z,y。
(2) 在第一个想法后,我们应该来思考它会出现哪些问题: 如何满足x,y,z的互质呢?
(3)果断动手写了几发。。。(动手测试非常重要呀)。。。冥冥之中有种感觉分解的两个数互质有很好的性质。
(4)吐槽自己一句:再验证性质的时候,自己没有好好记录分析过程,导致到了后面存在反复验证一些想法
(!!!!验证互质千万不要从gcd为1来思考呀,,那样坑爹呀,,直接枚举一个数的质因子,看另一个数是否存在)
假设 x^2 =a*b(a>b), z=(a+b)/2 ,y=(a-b)/2;
(1) 如果a,b都包含p这个素因子,那么 z=p*(……) /2 ,看到这里,会发现那个2真碍事。。
就先认为p!=2,因此(……)%2=0;最终z=p*(……)。。。同理y也是。。。
因此如果x%2!=0的情况下,,要满足题意,z,y中一定分配不相同的素因子;
要满足题意,还要与x也要互质,这个性质满足么?
用我上面加粗的那句话 :验证x中的所有素因子都不可能被 (a+b)/2 ,(a-b)/2 整除
对素因子p, a和b必定有一个能够整除它,假设a=p*A,则b%p!=0
反证: (a+b)/ 2 % p =0
→ (a+b)%(2*p) /2 = 0 → (a+b)%(2*p)=0 ( 定理: ( a/c )%p =a%(c*p)/c )
→ a+b=2*p*k → p*(2*k-A)=b 因为 b无法整除p,这个等式必定矛盾
故可以得到:在不考虑含有素因子2的情况下, 如果分解的两个数互质,那么
得到的x,y,z也是互质的
(2) 在分析x%2==0的时候,我二逼了。。导致这里花费了大量的时间。
对这个问题,,我们首先应该思考在包含素因子2的情况下,其它素因子的分配原则是否与上面一样
显然:不考虑同时素因子2的情况,对于其它素因子都是满足互质的
因此明确 不为2的相同素因子的分配依然要满足只能全部在一个数里(由上面可以证明)
考虑2的分配原则。
果断动手来一发: 6^2=2*18 → y=8 ,z=10 显然 x,y,z不互质
果断动手来一发: 4^2=2*8 → y=3 ,z=5 显然 x, y,z互质
这里看起来似乎没什么好的性质。。。
这里通过慢慢讨论,来认清它比较好的性质:
(1) 两个数当中必须至少有一个2,否则奇数+偶数无法整除2
(2)两个数中含2 的个数,不能同时大于两个
因为 这种情况下,(a+b)/2 的时候抵消一个2后,至少还剩有一个2,此时必定与x不互质
(3) 在前两个条件下,我们就能够得到2的分配方式:a含一个2 ,b含剩下所有的2 ,
但是这种分配与(1)的分配有区别,这里的分配是否能够保证得到的y,z不含2,
即是否与x互质?。。但是这个很好解决,判断一下是否含2就行了。
(4) 到此,这题的本质就基本成型了,但是对于2的分配,其实我们还有进行优化的余地:
分析: 6^2=2*18 不合法的原因
(a+b)/ 2= ( 2 * 1 + 2 * 9)/2 =2/2*(1+9)
原因就出在1+9 是偶数 ,2的分配原则一方含一个2,这个2就是为了
用来消除 即将( / 2),可是由于1+9产生了新的2,使得最终得到的
数是偶数与x不互质了。这里很容易发现:如果x^2中含有2的个数大于2,
这样产生的分配: 2*奇数 , 2*( 2^t*奇数) ,这样最终得到的y,z
必然都是两个奇数。
综上: 对x^2 中,不为2的素因子只能为一方所有
对于含有素因子2的情况,x含2的个数一定要大于1,分配原则: 一方1个2,另一方剩下的所有2
本题的实现:我写的比较慢。。。
大致思路: 对每个数就行分解(用上面的结论),然后看分解得到的数是否至少含有一个,如果有的情况,就把他们标记为同一个堆(并查集),最后check有多少个不同的堆,就是答案