hdoj-4790-Just Random【数论】

可以参考:http://www.cfanz.cn/?c=article&a=read&id=209350 讲的挺详细

Just Random

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


Problem Description
  Coach Pang and Uncle Yang both love numbers. Every morning they play a game with number together. In each game the following will be done:
  1. Coach Pang randomly choose a integer x in [a, b] with equal probability.
  2. Uncle Yang randomly choose a integer y in [c, d] with equal probability.
  3. If (x + y) mod p = m, they will go out and have a nice day together.
  4. Otherwise, they will do homework that day.
  For given a, b, c, d, p and m, Coach Pang wants to know the probability that they will go out.

Input
  The first line of the input contains an integer T denoting the number of test cases.
  For each test case, there is one line containing six integers a, b, c, d, p and m(0 <= a <= b <= 10 9, 0 <=c <= d <= 10 9, 0 <= m < p <= 10 9).

Output
  For each test case output a single line "Case #x: y". x is the case number and y is a fraction with numerator and denominator separated by a slash ('/') as the probability that they will go out. The fraction should be presented in the simplest form (with the smallest denominator), but always with a denominator (even if it is the unit).

Sample Input
  
  
4 0 5 0 5 3 0 0 999999 0 999999 1000000 0 0 3 0 3 8 7 3 3 4 4 7 0

Sample Output
  
  
Case #1: 1/3 Case #2: 1/1000000 Case #3: 0/1 Case #4: 1/1

Source

Recommend
We have carefully selected several similar problems for you: 5338 5337 5336 5335 5334

#include<stdio.h>
#include<algorithm>
using namespace std;
__int64 m,p; 
__int64 GCD(__int64 a,__int64 b){
	return !b?a:GCD(b,a%b);
}
__int64 f(__int64 a,__int64 b){
	__int64 ta,tb,ra,rb;
	if(a<0||b<0) return 0;
	ta=(a+1)/p; tb=(b+1)/p;
	ra=(a+1) %p; rb=(b+1)%p;
	__int64 ans=0;
	ans= p * ta * tb;
	if(!ra&&!rb) return ans;

	if(ra) ans+=ra*tb;
	if(rb) ans+=rb*ta;
	if(!ra||!rb) return ans;
	ra--;rb--;
	__int64 miny=(m-ra+p)%p;
	if(ra>m) {
		ans+=min(m+1,rb+1);
		if(miny<=rb)
		ans+=rb-miny+1;
	}
	else if(ra<m){
		if(miny<=rb)
		ans+=min(ra+1,rb-miny+1);
	}  		
	else if(ra==m) ans+=min(ra+1,rb+1);
	return ans;
}
int main(){
	int t,cas=0;;
	scanf("%d",&t);
	while(t--){
		++cas;
		__int64 a,b,c,d;
		scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&p,&m);
        __int64 u=f(b,d)-f(b,c-1)-f(a-1,d)+f(a-1,c-1);
        __int64 v=(b-a+1)*(d-c+1);
        __int64 s=GCD(u,v);
		printf("Case #%d: %I64d/%I64d\n",cas,u/s,v/s);;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值