容斥原理&lcm(2.22)As Firm As Stone

As Firm As Stone

Time Limit: 1000 ms  Memory Limit: 65536 KiB

Problem Description

这一天 Stone 又窝在宿舍里偷偷的玩 LOL 的无限火力,玩的当然是他最擅长的石头人,众所周知石头人有 4 个技能,在这里我们来简化一下,设置为 3 个技能,Q, W, E,对应的 CD(冷却时间)分别为 a, b, c。
Stone 有一个神奇的外挂,每按一次外挂的快捷键就会同时释放出当前可以释放的所有技能,而他是一个有强迫症的人,一旦出现可以释放的技能就会马上释放出去。
设游戏开始的时间为 0,游戏开始时 Stone 会按一次快捷键释放出所有技能。
Stone 想知道他在游戏开始后的第 n 秒和第 m 秒之间(包括第 n 秒和第 m 秒)需要按多少次快捷键。
但是今天 Stone 的智商下线了,他找到你来帮忙,并承诺给你找一个女朋友(如果你是女生,他就把自己送给你),你能帮他算一下吗?

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。
每组一行以空格隔开的 5 个整数 a, b, c(0 < a, b, c <= 2048),n, m(0 < n, m <= 10^9)。

Output

对于每组数据,输出一行一个整数,表示 Stone 在第 n 秒和第 m 秒之间需要按快捷键的次数。

Sample Input

1 2 3 1 10
4 5 6 1 100

Sample Output

10
46

Hint

如果某个技能的冷却时间为 3,那么从第 1 秒到第 10 秒这个时间区间里,在第 3, 6, 9 秒时他会释放这个技能。

#include <stdio.h>

long long l,r;//数据较大,int会爆,用long long
long long gcd(long long a,long long b){//求两个数的最大公约数
	return b?gcd(b,a%b):a;
}
long long lcm(long long a,long long b){//求两个数的最小公倍数
	return a*b/gcd(a,b);
}
long long num(long long a){//求解[l,r]区间内可以被a整除的数的个数
	return r/a-(l-1)/a;
}
int main(){
	long long a,b,c;
	while(~scanf("%lld %lld %lld %lld %lld",&a,&b,&c,&l,&r)){
		if(l>r){//如果左边界大于右边界,左右边界交换
			long long tmp = l;
			l = r;
			r = tmp;
		}
		printf("%lld\n",num(a)+num(b)+num(c)-num(lcm(a,b))-num(lcm(b,c))-num(lcm(a,c))+num(lcm(lcm(a,b),c)));
	}
	return 0;
}

区间 (l,r) (l<r) 内能整除某个数 a 的数的个数就是
num(a)=r/a-(l-1)/a,
那么求它们的和就是分别求出来相加再减去重复的即可,
两个数的重复的数量就是他们的最小公倍数 (lcm) 对应的数量,
两两减去重复的以后还要再加上它们 3 个的最小公倍数对应的数量。
所以最终答案为

num(a)+num(b)+num(c)-num(lcm(a,b))-num(lcm(b,c))-num(lcm(a,c))+num(lcm(lcm(a,b),c)))。




cyk: THE BIG HANDSOME GOD

Time Limit: 1000 ms  Memory Limit: 65536 KiB

Problem Description

One day, bLue met cyk and thought that cyk looked so handsome.

bLue wanted to be handsome like cyk, then he would be able to find a girl friend. So he asked cyk how can be handsome.

cyk said that there's an interesting problem and if bLue can solve it, he would teach him how to be handsome.

 

The problem is:

There's an exciting number k. You should calculate how many numbers in range [cy] is coprime (their GCD equals 1) with k.


For bLue's future, can you help him to solve the problem?

Input

The first line of input contains one integer T (0 < T <= 100), denoting the number of test cases.

For each case, it contains 3 integer cyk (0 < c <= y <= 10^15, 0 < k < 10^9) separated by spaces in one line.

Output

For each case, output an integer in one line, denoting the answer.

Sample Input

2
1 10 2
3 10 5

Sample Output

5
6

Hint

Source

【第八届山东理工大学ACM网络编程擂台赛 正式赛】Q^Q (cyk)

此题是个典型的容斥,首先明确一个概念,在 1~n 内 k 的倍数的数的个数为 n/k,所以我们把题目中的 k 用唯一分解定理分解掉(任何一个数都可以用 n 个素数相乘来表示,如 8=2*2*2);然后我们可以变通一下题意,n,m 之间和 k 互质的数的个数可以理解为 1~n 之间和 k 互质的个数减去1~m-1 之间和 k 互质的个数,然后用 n/(k所有的素因子) 来求解和 k 互质的数的个数,注意,这样肯能会除重了,如 6 既是 2 的倍数也是 3 的倍数,解决方法我们可以用容斥原理(奇加偶减,仔细想想,高中学过)就可以了,讲到这里代码一看就明白了。

cyk: THE BIG HANDSOME GOD

Time Limit: 1000 ms  Memory Limit: 65536 KiB

Problem Description

One day, bLue met cyk and thought that cyk looked so handsome.

bLue wanted to be handsome like cyk, then he would be able to find a girl friend. So he asked cyk how can be handsome.

cyk said that there's an interesting problem and if bLue can solve it, he would teach him how to be handsome.

 

The problem is:

There's an exciting number k. You should calculate how many numbers in range [cy] is coprime (their GCD equals 1) with k.


For bLue's future, can you help him to solve the problem?

Input

The first line of input contains one integer T (0 < T <= 100), denoting the number of test cases.

For each case, it contains 3 integer cyk (0 < c <= y <= 10^15, 0 < k < 10^9) separated by spaces in one line.

Output

For each case, output an integer in one line, denoting the answer.

Sample Input

2
1 10 2
3 10 5

Sample Output

5
6

Hint

Source

【第八届山东理工大学ACM网络编程擂台赛 正式赛】Q^Q (cyk)

题意:就是让你求(a,b)区间于n互质的数的个数.

分析:我们可以先转化下:用(1,b)区间与n互质的数的个数减去(1,a-1)区间与n互质的数的个数,那么现在就转化成求(1,m)区间于n互质的数的个数,如果要求的是(1,n)区间与n互质的数的个数的话,我们直接求出n的欧拉函数值即可,可是这里是行不通的!我们不妨换一种思路:就是求出(1,m)区间与n不互质的数的个数,假设为num,那么我们的答案就是:m-num!现在的关键就是:怎样用一种最快的方法求出(1,m)区间与n不互质的数的个数?方法实现:我们先求出n的质因子(因为任何一个数都可以分解成若干个质数相乘的),如何尽快地求出n的质因子呢?我们这里又涉及两个好的算法了!第一个:用于每次只能求出一个数的质因子,适用于题目中给的n的个数不是很多,但是n又特别大的;(http://www.cnblogs.com/jiangjing/archive/2013/06/03/3115399.html)第二个:一次求出1~n的所有数的质因子,适用于题目中给的n个数比较多的,但是n不是很大的。(http://www.cnblogs.com/jiangjing/archive/2013/06/01/3112035.html)本题适用第一个算法!举一组实例吧:假设m=12,n=30.

第一步:求出n的质因子:2,3,5;

第二步:(1,m)中是n的因子的倍数当然就不互质了(2,4,6,8,10)->n/2  6个,(3,6,9,12)->n/3  4个,(5,10)->n/5  2个。

如果是粗心的同学就把它们全部加起来就是:6+4+2=12个了,那你就大错特错了,里面明显出现了重复的,我们现在要处理的就是如何去掉那些重复的了!

第三步:这里就需要用到容斥原理了,公式就是:n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5).

第四步:我们该如何实现呢?我在网上看到有几种实现方法:dfs(深搜),队列数组,位运算三种方法都可以!上述公式有一个特点:n除以奇数个数相乘的时候是加,n除以偶数个数相乘的时候是减。我这里就写下用队列数组如何实现吧:我们可以把第一个元素设为-1然后具体看代码如何实现吧!

同种类型的题目:hdu 2841    hdu1695

代码实现:

 

复制代码
#include<iostream>
#include<string.h>
using namespace std;
__int64 a[1000],num;
void init(__int64 n)//求一个数的质因子
{
    __int64 i;
    num=0;
    for(i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            a[num++]=i;
            while(n%i==0)
                n=n/i;
        }
    }
    if(n>1)//这里要记得
        a[num++]=n;
}
__int64 haha(__int64 m)//用队列数组实现容斥原理
{
    __int64 que[10000],i,j,k,t=0,sum=0;
    que[t++]=-1;
    for(i=0;i<num;i++)
    {
        k=t;
        for(j=0;j<k;j++)
           que[t++]=que[j]*a[i]*(-1);
    }
    for(i=1;i<t;i++)
        sum=sum+m/que[i];
    return sum;
}
int main()
{
    __int64 T,x,y,n,i,sum;
    while(scanf("%I64d",&T)!=EOF)
    {
        for(i=1;i<=T;i++)
        {
           scanf("%I64d%I64d%I64d",&x,&y,&n);
           init(n);
           sum=y-haha(y)-(x-1-haha(x-1));
           printf("Case #%I64d: ",i);
           printf("%I64d\n",sum);
        }
    }
    return 0;
}
复制代码

 

 

cyk: THE BIG HANDSOME GOD

Time Limit: 1000 ms  Memory Limit: 65536 KiB

Problem Description

One day, bLue met cyk and thought that cyk looked so handsome.

bLue wanted to be handsome like cyk, then he would be able to find a girl friend. So he asked cyk how can be handsome.

cyk said that there's an interesting problem and if bLue can solve it, he would teach him how to be handsome.

 

The problem is:

There's an exciting number k. You should calculate how many numbers in range [cy] is coprime (their GCD equals 1) with k.


For bLue's future, can you help him to solve the problem?

Input

The first line of input contains one integer T (0 < T <= 100), denoting the number of test cases.

For each case, it contains 3 integer cyk (0 < c <= y <= 10^15, 0 < k < 10^9) separated by spaces in one line.

Output

For each case, output an integer in one line, denoting the answer.

Sample Input

2
1 10 2
3 10 5

Sample Output

5
6

Hint

Source

【第八届山东理工大学ACM网络编程擂台赛 正式赛】Q^Q (cyk)

01 #include<iostream>
02 #include<string.h>
03 #include<bits/stdc++.h>
04 using namespace std;
05 long long a[108],num;
06 void init(long long n)
07 {
08     long long i;
09     num=0;
10     for(i=2;i*i<=n;i++)
11     {
12         if(n%i==0)
13         {
14             a[num++]=i;
15             while(n%i==0)
16                 n=n/i;
17         }
18     }
19     if(n>1)//这里要记得
20         a[num++]=n;
21 }
22 long long haha(long long m)//用队列数组实现容斥原理
23 {
24     long long que[10000],i,j,k,t=0,sum=0;
25     que[t++]=-1;
26     for(i=0;i<num;i++)
27     {
28         k=t;
29         for(j=0;j<k;j++)
30            que[t++]=que[j]*a[i]*(-1);
31     }
32     for(i=1;i<t;i++)
33         sum=sum+m/que[i];
34     return sum;
35 }
36 int main() {
37     long long a,b,k;
38     int t;
39     scanf("%d",&t);
40     while(t--){
41         num=0;
42         scanf("%lld%lld%lld",&a,&b,&k);
43         init(k);
44         printf("%lld\n",b-haha(b)-(a-1-haha(a-1)));
45     }
46  
47     return 0;
48 }

cyk: THE BIG HANDSOME GOD

Time Limit: 1000 ms  Memory Limit: 65536 KiB

Problem Description

One day, bLue met cyk and thought that cyk looked so handsome.

bLue wanted to be handsome like cyk, then he would be able to find a girl friend. So he asked cyk how can be handsome.

cyk said that there's an interesting problem and if bLue can solve it, he would teach him how to be handsome.

 

The problem is:

There's an exciting number k. You should calculate how many numbers in range [cy] is coprime (their GCD equals 1) with k.


For bLue's future, can you help him to solve the problem?

Input

The first line of input contains one integer T (0 < T <= 100), denoting the number of test cases.

For each case, it contains 3 integer cyk (0 < c <= y <= 10^15, 0 < k < 10^9) separated by spaces in one line.

Output

For each case, output an integer in one line, denoting the answer.

Sample Input

2
1 10 2
3 10 5

Sample Output

5
6

Hint

Source

【第八届山东理工大学ACM网络编程擂台赛 正式赛】Q^Q (cyk)

猜你喜欢

转载自blog.csdn.net/beposit/article/details/79348952