UVA - 1393 Highways (和紫书不一样的解法)

题目链接

题解:

由于我的方法和紫书不一样,所以专门写一下记录一下解题思路。

显然“\”和“/”两个方向的直线数量是相同的,所以我们考虑计算“/”方向的线的数量。

统计类问题,都需要找到合适的分类方法,使我们能够不重复、不遗漏的统计出所有情况。

本题我们以直线的起点分类,把直线分类,来进行统计。

对于点UVA - 1393 Highways (和紫书不一样的解法),其右上角有UVA - 1393 Highways (和紫书不一样的解法)个点,总共可以连UVA - 1393 Highways (和紫书不一样的解法)条直线,其中某些直线重复出现,假如我们计算出只出现了一次的直线有多少条记为UVA - 1393 Highways (和紫书不一样的解法)。那么所有点的UVA - 1393 Highways (和紫书不一样的解法)的和,即UVA - 1393 Highways (和紫书不一样的解法),就是我们的答案。

很容易证明,对于每条直线,我们只会在最右上角那一段计算一次,所以不会有重复,我们计算了所有起点,所以没有遗漏。

对于每一个点UVA - 1393 Highways (和紫书不一样的解法),如何计算UVA - 1393 Highways (和紫书不一样的解法) ?

我们设点UVA - 1393 Highways (和紫书不一样的解法)为坐标源点,设其右上角的点坐标为UVA - 1393 Highways (和紫书不一样的解法)

我们要直线UVA - 1393 Highways (和紫书不一样的解法)只出现一次,那么UVA - 1393 Highways (和紫书不一样的解法)一定要同时满足以下条件:

1,UVA - 1393 Highways (和紫书不一样的解法)

2,UVA - 1393 Highways (和紫书不一样的解法) 或 UVA - 1393 Highways (和紫书不一样的解法)

如何计算满足条件的UVA - 1393 Highways (和紫书不一样的解法)有多少对呢?

我们设UVA - 1393 Highways (和紫书不一样的解法)为有多少对UVA - 1393 Highways (和紫书不一样的解法)互质?即UVA - 1393 Highways (和紫书不一样的解法)

那么UVA - 1393 Highways (和紫书不一样的解法) 就是要求解的答案。

如何计算UVA - 1393 Highways (和紫书不一样的解法)呢?

我们可以递推计算 UVA - 1393 Highways (和紫书不一样的解法)UVA - 1393 Highways (和紫书不一样的解法)表示数字1到UVA - 1393 Highways (和紫书不一样的解法)有多少个数和UVA - 1393 Highways (和紫书不一样的解法)互素。

我们可以暴力预处理出所有UVA - 1393 Highways (和紫书不一样的解法)

复杂度

预处理UVA - 1393 Highways (和紫书不一样的解法)的复杂度UVA - 1393 Highways (和紫书不一样的解法)

每次询问计算的复杂度UVA - 1393 Highways (和紫书不一样的解法)

所以复杂度为UVA - 1393 Highways (和紫书不一样的解法)

代码如下:

#include<bits/stdc++.h>

using namespace std;
const int nn =11000000;
const int inff = 0x3fffffff;
const double eps = 1e-8;
typedef long long LL;
const double pi = acos(-1.0);
const LL mod = 1000000007;
int f[310][310];
int GCD(int a,int b)
{
    if(b==0)
        return a;
    return GCD(b,a%b);
}
void init()
{
    memset(f,0,sizeof(f));
    int pre[310];
    memset(pre,0,sizeof(pre));
    for(int i=1;i<=300;i++)
    {
        f[i][1]=f[i-1][1]+1;
        for(int j=1;j<=300;j++)
        {
            if(GCD(i,j)==1)
                pre[j]++;
        }
        for(int j=2;j<=300;j++)
        {
            f[i][j]=f[i][j-1]+pre[j];
        }
    }
}
int main()
{
    init();
    int n,m;
    while(cin>>n>>m)
    {
        if(n==0&&m==0)
            break;
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                ans+=f[i-1][j-1]-f[(i-1)/2][(j-1)/2];
            }
        }
        cout<<ans*2<<endl;
    }
    return 0;
}

 

上一篇:UVA 1073 Glenbow Museum


下一篇:数据结构:栈 - UVA 514 - Rails