1. 程式人生 > >A】無序組數 (思維,數學,因子個數)

A】無序組數 (思維,數學,因子個數)

題幹:

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 131072K,其他語言262144K 64bit IO Format: %lld

題目描述

給出一個二元組(A,B) 求出無序二元組(a,b) 使得(a|A,b|B)的組數 無序意思就是(a,b)和(b,a) 算一組.

輸入描述:

第一行資料組數 T(1≤T≤10000)
接下來T行,每行兩個正整數 A,B(1≤A,B≤10000)

輸出描述:

共T行,每行一個結果

示例1

輸入

複製

1
4 6

輸出

複製

11

說明

樣例解釋:
二元組如下:
(1,1)(1,2)(1,3)(1,6)
(2,1)(2,2)(2,3)(2,6)
(4,1)(4,2)(4,3)(4,6)
共12組.
無序二元組如下:

(1,1)(1,2)(1,3)(1,6)
(2,2)(2,3)(2,6)
(4,1)(4,2)(4,3)(4,6)
共11組

解題報告:

   題目要求無序對,我們先想象成有序對,然後再減去重複的,就是最終答案了。

   有序對很好求,先打表出每一個數的因子個數,然後a和b的因子數相乘,就是有序對的個數,然後減去他倆最大公約數的因子個數(也就是重複了一次的個數)(此處用等差數列求和公式去求(可以認為公差為0的等差數列)),得到的就是答案了。

AC程式碼:

#include<bits/stdc++.h>
using namespace std;
int d[100010];
int T;
int main(){
    for(int i=1;i<100010;i++)
        for(int j=i;j<100010;j+=i)
            d[j]++;
    scanf("%d",&T);
    for(;T--;){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",d[a]*d[b]-d[__gcd(a,b)]*(d[__gcd(a,b)]-1)/2);
    }
    return 0;
}