题目描述
正如我们所知道的那样,Jack Sparrow不仅仅是一名海盗,同时他也是一名出色的数学家。
在Jack击败EIC(东印度公司)和Davy Jones后,Jack 拥有了众多的船只。
这些船只可粗略的分为两大类:一类来自EIC,一类来自Davy Jones(注意,两者可能有交集)。而Jack将这两类船只抽象为两个集合:集合E,集合D。
管理众多的船只时,往往需要一种很繁琐的集合操作:α。对于集合操作α,Jack定义为: E α D=E∪D-E∩D。
ok,现在Jack需要取出集合对{A,B},并且满足: A∈E B∈D 使得: (A α E)α(B α D)=E α D,其中A,B都是集合。
例如:E={1},D={1,2},那么EαD = {2},符合条件的{A,B}共有2种。
Jack需要知道的是,这样的集合对存在多少?答案对1e9+7取模。
输入
输入包含多组测试数据,每组数据包含三个正整数 L1,L2,L3(L1,L2,L3 <= 1e18),分别表示|E|,|D|,|E∩D|。
输出
输入答案,答案对1e9+7取模。
样例输入
复制
1 2 1
样例输出
复制
2
形象表示一下这个自定义符号运算α
E α D=(除去图中阴影部分)
由 A∈E B∈D,得
A α E=E-A;B α D=D-B;
(A α E)α(B α D)=E α D,要想使得等式成立,A和B必须在阴影部分取(也就是两个集合的交集)并且A和B的元素要相同。
用集合论来说就是求E和D交集的幂集元素个数,也就是2^L3(L3表示E和D交集元素个数)
换种方式说就是就排列组合数
还有一点需要注意的是指数比较大,需要用到快速幂。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 #include<queue> 6 using namespace std; 7 #define LL long long 8 #define INT 0x7fffffff 9 LL mod=1e9+7; 10 LL quick_pow(LL n, LL k) 11 { 12 LL ans=1; 13 n=n%mod; 14 while(k) 15 { 16 if(k&1) 17 ans=ans*n%mod; 18 n=n*n%mod; 19 k/=2; 20 } 21 return ans; 22 } 23 int main() 24 { 25 LL r1, r2, r3; 26 while(scanf("%lld%lld%lld", &r1, &r2, &r3)!=EOF) 27 { 28 LL ans=quick_pow((LL)2, r3); 29 printf("%lld\n", ans); 30 } 31 return 0; 32 }