关闭

HDU2841 一个关于互质的容斥

142人阅读 评论(0) 收藏 举报
分类:

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

这题主要就是求多少种斜率的问题
每个斜率对应的都只有一棵树
因为后边的会被挡住

斜率的分子和分母是一定互质的

但是肯定不能一个一个求得…那肯定要炸,mn的范围都是1到10万
而我实在想不出什么可以找规律缩到logn这种诡异解法

所以剪一下枝

首先固定一个n,用来找每一个n在m中有几个互质的数
如何与n互质呢…只要和n没有公约数就可以了
所以我们可以分解一下n的质因子
对就是这里,因为分解的是质因子
因此做题前可以进行预处理…
先用艾氏筛法晒下素数…….
找出它的质因子以后就可以就可以容斥了…
又是老一套…

其实这题很简单,但是这么大的数据总是让我感觉我枚举的话会超时…
可是实际上根本不会…这就是正确方法….
以后做题的时候应该先交上试试了……

另外这次出现了一个新的问题需要注意
那就是筛完了素数以后,素数的个数要记住…
在循环的时候不能让坐标大于这个数
因为声明的是全局变量所以在素数小于m的时候再迭代一次下次取值就是0
再膜就会取到0

re无数次

#include <iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<memory.h>
using namespace std;
int sushu[100001];
int sus[100001];
int susu=0;
int n,m;
int ss[200];
int he[200];
int uu=0;
void dfs(int zuobiao,int ceng,int zong)
{
    if(ceng>uu)return ;
    if(zong>m)return;
    else
    {
        int tem=zong*ss[zuobiao];
        he[ceng]+=m/tem;
        for(int a=zuobiao+1;a<=uu;a++)dfs(a,ceng+1,tem);
    }
}
int main()
{
    for(int a=2;a*a<=100000;a++)
    {
        if(sushu[a]==1)continue;
        sus[++susu]=a;
        for(int b=a+a;b<=100000;b+=a)sushu[b]=1;
    }
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;
        long long sum=m;
        for(int a=2;a<=n;a++)
        {
            memset(ss,0,sizeof(ss));
            memset(he,0,sizeof(he));
            uu=0;
            int y=a;
            for(int b=1;sus[b]<=y&&b<=susu;b++)
            {
                if(a%sus[b]==0)
                {
                    ss[++uu]=sus[b];
                    while(y%sus[b]==0)y/=sus[b];
                }
            }
            if(y!=1)ss[++uu]=y;
            for(int q=1;q<=uu;q++)dfs(q,1,1);
            for(int q=1;q<=uu;q++)if(q%2)he[q]=-he[q];
            sum+=m;
            for(int q=1;q<=uu;q++)sum+=he[q];
        }
        cout<<sum<<endl;
    }
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:27051次
    • 积分:3190
    • 等级:
    • 排名:第10792名
    • 原创:308篇
    • 转载:0篇
    • 译文:0篇
    • 评论:8条
    最新评论