选拔赛 c 武器大师的宝贝
Description
武器大师有两堆宝贝箱子,每个箱子都有着自己的一个编号。
为了输入方便,每堆箱子编号都是连续的。
现在他想分别从两堆箱子中各等概率的选择一个箱子,但是只有他选择的两个箱子编号异或(位运算)之后为0,他才能获得奖励。
现在他想请你算算每次他能获得奖励的概率。
为了防止精度误差,你需要输出一个形如a/b的最简分数。
特别的,如果概率为0,你需要输出0/1。
(有人不知道啥是异或吗?
Input
第一行一个正整数T(1<=T<=1000),表示数据组数。
接下来每一行都有一组数据,每组数据输入4个整数a,b,c,d,表示两堆箱子的编号区间分别为[a,b],[c,d]。
(a, b, c, d∈[0, 1e9],a ≤ b,c ≤ d)
Output
对每组数据输出他能获得奖励的概率。一个形如a/b的最简分数。
特别的,如果概率为0,你需要输出0/1。
Sample Input 1
8 1 2 2 3 1 2 2 4 1 1 1 1 1 1 2 2 829 24970 7181 23584 1689 21354 18463 48102 1 2 1 2 100 100 2 17
Sample Output 1
1/4 1/6 1/1 0/1 1/24142 241/48575020 1/2 0/1
Hint
样例一:有两堆箱子,第一堆箱子有2个箱子,编号为分别为1,2。第二堆箱子也有2个箱子,编号为2,3。只有当选择的箱子对是(2,2)时他才能获得奖励。
解释位运算异或:0^0=0,0^1=1,1^0=1,1^1=0.
例如:3^5 = 011^101=110
Source
2019年集训队选拔赛
讲道理,异或,看他两个同不同就行,一样异或的结果就是0
所就是看一个区间里的数在不在后面那个区间就行了
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; #define INF 0x3f3f3f3f; #define ll long long bool isEven(ll x) { if ((x & 1) == 0) { return true; } else { return false; } } ll gcd(ll x, ll y) { if (x < y) { return gcd(y, x); } if (y == 0) { return x; } else { if (isEven(x)) { if (isEven(y)) { return (gcd(x >> 1, y >> 1) << 1); } else { return gcd(x >> 1, y); } } else { if (isEven(y)) { return gcd(x, y >> 1); } else { return gcd(y, x - y); } } } } int main() { int t; cin>>t; while(t--) { ll a,b,c,d; ll sum=0; cin>>a>>b>>c>>d; for(ll i=a; i<=b; i++) { if(i>=c&&i<=d) sum++; } ll z=(b-a+1)*(d-c+1); if(sum==0) cout<<"0/1"<<endl; else if(sum==z) cout<<"1/1"<<endl; else { ll q=gcd(sum,z); cout<<sum/q<<"/"<<z/q<<endl; } } return 0; }