hdu2848 Visible Trees (容斥原理)
2016-04-09 21:06
344 查看
题意: 给n*m个点(1 ≤ m, n ≤ 1e5),左下角的点为(1,1),右上角的点(n,m),一个人站在(0,0)看这些点。在一条直线上,只能看到最前面的一个点,后面的被档住看不到,求这个人能看到多少个点。 知识点: 容斥原理:(容许) 先不考虑重叠的情况,把包含于某条件中的所有对象的数目先计算出来,(排斥)然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复。 公式:
奇加偶减
一般求互质个数若用欧拉函数不好解决,则从反面考虑,用容斥。
模板:
题解:在同一条直线上的点的形式都是(ka,kb),这些点只能看到第一个。若gcd(a,b)==k’,(k’!=1),则其还能写成 (k’a’,k’b’)的形式。直到gcd(a,b)==1,(a,b)为第一个点。That is say,只要求出1~n与1~m中互质的数的个数,这题就OK了。一般求互质个数若用欧拉函数不好解决,则从反面考虑,用容斥。x为1~n中的一个数,x与1~m中互质的数的个数怎么求呢?用容斥,先找到有多少个数和x有1个公共的质因子,然后加上;再找到有多少个数与x有2个公共的质因子,然后减去;再找到有多少个数有多少个数与x有3个公共的质因子,然后加上……最后得到的个数,就是有多少个数与x不互质。
Visible Trees
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status
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
Sample Output
奇加偶减
一般求互质个数若用欧拉函数不好解决,则从反面考虑,用容斥。
模板:
void dfs(int c,int cur,int i,int j,LL ans1) //dfs(c,1,i,0,1); { if(cur==c+1) { if(c&1) ans-=ma/ans1; else ans+=ma/ans1; return; } for(;j<cnt[i];j++) { dfs(c,cur+1,i,j+1,ans1*syz[i][j]); } }
题解:在同一条直线上的点的形式都是(ka,kb),这些点只能看到第一个。若gcd(a,b)==k’,(k’!=1),则其还能写成 (k’a’,k’b’)的形式。直到gcd(a,b)==1,(a,b)为第一个点。That is say,只要求出1~n与1~m中互质的数的个数,这题就OK了。一般求互质个数若用欧拉函数不好解决,则从反面考虑,用容斥。x为1~n中的一个数,x与1~m中互质的数的个数怎么求呢?用容斥,先找到有多少个数和x有1个公共的质因子,然后加上;再找到有多少个数与x有2个公共的质因子,然后减去;再找到有多少个数有多少个数与x有3个公共的质因子,然后加上……最后得到的个数,就是有多少个数与x不互质。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int ma,mi;
LL ans;
int syz
[7]; //素因子分解结果
int cnt
;
void init() //筛选法求syz
{
memset(cnt,0,sizeof(cnt));
for(int i=2;i<N;i++)
{
if(cnt[i]==0)
{
for(int j=i;j<N;j+=i)
{
syz[j][cnt[j]++]=i;
}
}
}
}
void dfs(int c,int cur,int i,int j,LL ans1) //dfs(c,1,i,0,1); { if(cur==c+1) { if(c&1) ans-=ma/ans1; else ans+=ma/ans1; return; } for(;j<cnt[i];j++) { dfs(c,cur+1,i,j+1,ans1*syz[i][j]); } }
int main()
{
int t;
cin>>t;
init();
LL m,n;
while(t--)
{
scanf("%lld%lld",&m,&n);
ans=m*n;
ma=max(m,n),mi=min(m,n);
for(int i=2;i<=mi;i++)
{
for(int c=1;c<=cnt[i];c++)
{
dfs(c,1,i,0,1);
}
}
printf("%I64d\n",ans);
}
return 0;
}
/*
100
23 54
56 54
44 54
10 10
100000 100000
*/
Visible Trees
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status
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
相关文章推荐
- JavaScript数组增加新的项
- [机器学习] Coursera ML笔记 - 逻辑回归(Logistic Regression)
- 求助:python中深拷贝和浅拷贝的一道题目
- HDU_1166_敌兵布阵
- Elasticsearch 运维实战之1 -- 集群规划
- HDOJ 2059 龟兔赛跑
- while(cin >> s)结束问题
- 关于CCNA的培训课程(3)-- Vlan VTP 中继 单臂路由 生成树协议
- 常用算法之堆排原理介绍与java实践
- Realm Android简单使用说明
- 参与众筹,擦亮你的眼,评测众筹产品minifox智能电动车
- Ajax文件上传,显示进度条
- Android中MediaPlayer的简单使用
- js跨域请求小结
- 斐波那契(Fibonacci)数列
- oracle 多个with as
- 计算机网络的客户和服务及它们的方式
- linux fsck 修复命令
- 深入浅出大数阶乘
- 半小时就让你损失几十万的一条命令