hdu 2841 树围成矩阵,人在(0,0)点,最多可看到几棵树

题意:有一个n*m的矩阵上布满了树(矩阵从(1,1)开始),现在有一个农夫站在(0,0)点,问农夫可以看到多少棵树,其中如果这些树在一条线上那么只能看到最前面的那棵树,这个一开始看到确实蒙了。。看了题解其实是挺简单的。首先考虑只能看到一条线上最前面的那棵树这个条件,对于坐标
比如 (2,3)(4,6)(6,9)。。等 这些坐标是在一条直线上的 可以看出其除了(2,3) 其他的都是由(2,3)的x坐标*k y坐标*k 得到的, 拓展出来就是对于 任意坐标 (x,y) 令a=x/gcd(x,y) b=y/gcd(x,y) 那么那些和(x,y) 在一条直线的点的坐标可以表示为 (x+(-)a*k,y+(-)b*k) ,显然(a,b) 是这条线上的第一个点,即农夫可以看到的点,所以总的问题就可以转换为求x∈(1,n)y∈(1,m)范围内满足 x,y互质的坐标的个数。枚举(1,n)内的x坐标
,求x与(1,m)内互质的数个数。

Problem Description

There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherlock is standing at (0,0) point. He wonders how many trees he can see.

If two trees and Sherlock are in one line, Farmer Sherlock can only see the tree nearest to him.

Input

The first line contains one integer t, represents the number of test cases. Then there are multiple test cases. For each test case there is one line containing two integers m and n(1 ≤ m, n ≤ 100000)

Output

For each test case output one line represents the number of trees Farmer Sherlock can see.

Sample Input

2
1 1
2 3

Sample Output

1
5
#include<stdio.h>
#include<iostream>
using namespace std;
int s[100020],k;
void init(int m)
{
    k=0;
    for(int i=2;i*i<=m;i++)
    {
        if(m%i==0)
            {s[k++]=i;
        while(m%i==0)
            m/=i;
            }
    }
    if(m>1)
        s[k++]=m;
}
int quc(int m)
{
    int t=0,p[100020],z;
    long long sum=0;
    p[t++]=-1;
    for(int i=0;i<k;i++)
    {
         z=t;
        for(int j=0;j<z;j++)
        {
            p[t++]=p[j]*s[i]*(-1);
        }
    }
    for(int i=1;i<t;i++)
    {
        sum+=m/p[i];
    }
    return sum;
}
int main()
{
    int n,a,b;
    long long sum;
    scanf("%d",&n);
    while(n--)
    {sum=0;
  scanf("%d %d",&a,&b);
    for(int i=1;i<=a;i++)
           {init(i);
           sum+=b-quc(b)+quc(0);
           }
           printf("%I64d\n",sum);
    }
}
时间: 2024-10-03 14:42:36

hdu 2841 树围成矩阵,人在(0,0)点,最多可看到几棵树的相关文章

hdu 2841 Visible Trees(计数问题)

题目链接:hdu 2841 Visible Trees 题目大意:一个n?m的矩阵,每个整数点上有树,人站在(0,0)点,问可以看见多少棵树. 解题思路:和uva1393是一道相同类型的题目,只不过这道题目的n比较大,不能预处理.必须用另外一种方法. 将矩阵按照(0,0)和(n,m)两天连成的直线分成两部分,分别计算,但是(n,m)这条线被计算了两次,于是减掉1. dp[i]表示这一列上有多少个点是可以被看见的,因为矩阵被对半分了,所以点的个数为m?in,同时还要计算每次看见的点会把后面的给挡住

小希的迷宫(MST单棵树判断法则)

小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 27851    Accepted Submission(s): 8613 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双

R语言基于树的方法:决策树,随机森林,套袋Bagging,增强树

原文链接:http://tecdat.cn/?p=9859 概观 本文是有关  基于树的  回归和分类方法的.用于分割预测变量空间的分割规则可以汇总在树中,因此通常称为  决策树  方法. 树方法简单易懂,但对于解释却非常有用,但就预测准确性而言,它们通常无法与最佳监督学习方法竞争.因此,我们还介绍了装袋,随机森林和增强.这些示例中的每一个都涉及产生多个树,然后将其合并以产生单个共识预测.我们看到,合并大量的树可以大大提高预测准确性,但代价是损失解释能力. 决策树可以应用于回归和分类问题.我们将

300个人围成一个圈,从某个指定的人开始报数(1--3),凡是数到3的人退出圈子

public static void main(String[] args) { /* * 300个人围成一个圈,从某个指定的人开始报数(1--3),凡是数到3的人退出圈子, * 问最后剩下的一个是从指定位置开始计数的第几个人? */ int num[]=new int[300]; int i=0; // 数组的下标计数器 0---299 int count=0; // 退出的人数计数器 0---299 int n=1; // 数数的计数器 1---3 while(count<299){ //

HDU 4902 Nice boat 成段线段树

操作1 的时候标记deng[rt]表示下面一段数都是与当前节点的值相同 下次操作2时直接对有deng标记的节点gcd更新 (可能还可以更简单) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #incl

hdu 1698 Just a Hook(线段树之 成段更新)

Just a Hook                                                                             Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description In the game of DotA, Pudge's meat hook is actually the mos

HDU 3397 Sequence operation (线段树,成段更新,区间合并)

http://acm.hdu.edu.cn/showproblem.php?pid=3397 Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5801    Accepted Submission(s): 1713 Problem Description lxhgww got a sequence

HDU 1159 Common Subsequence--DP--(转化成矩阵)

题意:找最长公共子序列(不要求连续) 分析:二维dp肯定的,不过我自己用的四层循环,超时:正解是画矩阵,找规律.以后要多注意这种思想 WA了很多遍,原因:1.对数组边界的处理:2.while(1)超时,改成while(cin>>a>>b)就过了 代码: #include<cstring> #include<cstdio> #define max(a,b) a>b?a:b using namespace std; char a[1005],b[1005]

HDU 6155 Subsequence Count(矩阵 + DP + 线段树)题解

题意:01串,操作1:把l r区间的0变1,1变0:操作2:求出l r区间的子序列种数 思路:设DP[i][j]为到i为止以j结尾的种数,假设j为0,那么dp[i][0] = dp[i - 1][1] + dp[i -1][0] (0结尾新串) + dp[i - 1][0] (0结尾旧串) - dp[i - 1][0] (重复) + 1(0本身被重复时去除). 那么可以得到转移时的矩阵 $$ \left( \begin{matrix} dp[i - 1][0] & dp[i - 1][1] &am