HDU_2841_Visible Trees && NYOJ_471_好多的树 容斥定理

HDU  Visible Trees

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2449    Accepted Submission(s): 1027


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
 

Source

NYOJ___好多的树

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
描述

在那遥远的地方有一片神奇的森林,它的神奇之处是:森林中的每棵树都长在一对整数确定的坐标上。有一个小红人站在(0,0)的位置上,放眼望去,看到很多的树,眼前的树是那么的多,以至于它一直数不清。那么就来写个程序帮它数数吧!

 

输入
第一行一个整数n,代表测试数据组数。
接下来有n(n<=20)行数,每行数有两个整数i,j代表任何的(x,y)(0<x<=i<=100000,0<y<j<=100000)的整数坐标上都有一棵树。
小红人始终是站在(0,0) 点上看树的。
输出
输出小红人看到的树的个数。每个结果占一行。
样例输入
1
7 4
样例输出
20

  求区间范围内的所有数的所有素因子,利用容斥定理去重

#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
int vis[100002];
vector<int>a[100002];

void init()    //筛选法求出 区间范围内所有数的  所有素因子
{ 
	int i,j;
	memset(vis,0,sizeof(vis));
    for(i=0;i<100002;i++)
       a[i].clear();
    for(i=2;i<=100000;i++)
    {
        if(vis[i]==0)//i是素数
        {
            a[i].push_back(i);
            for(j=i+i;j<=100000;j+=i)//筛选素数
            {
                vis[j]=1;
                a[j].push_back(i);
            }
        }
    }
}
long long dfs(int i,int n,int idx)
{
	int j;
    long long ret=0;
    for(j=idx;j<a[i].size();j++)
    {
        ret += n/a[i][j] - dfs(i,n/a[i][j],j+1);
    }
    return ret;
}
int main()
{
    init();
    int t,n,m,i;
    scanf("%d",&t);
    while(t--)
	{
        scanf("%d%d",&n,&m);
        if(n<m)  //因为对称位置 答案一样,后面小 减少循环次数 
        {
        	int z = n;
        	n = m;
        	m = z;
        }
        long long res = n;        //当i为1的时候肯定为n
        for(i=2;i<=m;i++)
        {
            res += n - dfs(i,n,0);
        }
        printf("%lld\n",res);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值