cocktail with hearthstone(组合数+找规律+一点点的dp思想+快速幂)
作者:互联网
Mr. Cocktail like a game named Hearthstone. In this game, there is a game mode "Arena" with the four rules as follows. 1.The record of each player is described as (a,b)(a,b), where aa means number of wins, and bb means number of losses. At the beginning of the game, the record is (0,0), that is, 0 wins and 0 losses. 2.For each round, the number of wins in winner's record will be added one point. And the defeated one will be added one point in the number of losses in his record. There is no tie in this game. 3.Each round will be start between two persons with same record. That is, when your record is (a, b), your opponent's record is also (a, b). Obviously, a player with a record of (a+1, b) will be produced after each round, and a record of (a, b+1) players. 4.When someone win N times or lost M times , he will automatically exit and end his game. In order for everyone to have an opponent before the end of the game, 2^{n+m}2 n+m players were assigned to participate by Mr. Cocktail. He will ask q times, and each time he give a, ba,b and want to know how many people were automatically out of the game with a record of (a,b)(a,b). (Guaranteed that (a,b)(a,b) meets the exit conditions). Since the answer may be very large, you only need to output the result after the answer is modulo 10^9+710 9 +7. Input In the first line input three integer n,m,q(1 \leq m < n \leq 2 \times 10^5, 1 \leq q \leq 2 \times 10^5)n,m,q(1≤m<n≤2×10 5 ,1≤q≤2×10 5 ) as described in statement. Then it will input qq lines data. every line will only contain two integer a, ba,b(0 \leq a \leq n, 0 \leq b \leq m0≤a≤n,0≤b≤m, ensure that b == m or a == n ). Output For each query, output an integer on a line to indicate the answer. Sample 1 Inputcopy Outputcopy 2 1 1 0 1 4 Note A total of 2^{2+1}=82 2+1 =8 people with record (0,0)(0,0) participating in this game. After the first round, 4 (1,0)(1,0) and 4 (0,1)(0,1) are generated. Among them, (0,1)(0,1) is eliminated directly, and there will be no players with (0,1)(0,1) records in subsequent matches, so the answer is 4.View problem
swjtu—春季集训 - Virtual Judge (vjudge.net)
思路:
- 这种类型的题,可以利用小数据把每一个节点写出来,观察规律,(打表的思想)
- dp思想: a,m 必定是由 a,m-1 推过去的,因此求出a,m-1的情况/2 就是答案
- 而且应为 a,m-1 一定是还没有人退出去, (a,b 都没有到达极限)所以可以利用类似二插树图所弄出的规律
- 先求出 那一层的 单位元素的 情况个数, 在看看有几个a,m-1的单位元素(这里就用组合数,他是满足这个组合规律的,Ca+m-1,a就行拉)
- 相乘就是答案了。
- 详细看代码
#include <bits/stdc++.h> using namespace std; #define ri register int #define M 400005 template <class G> void read(G &x) { x=0;int f=0;char ch=getchar(); while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x=f?-x:x; return ; } const int mod=1e9+7; long long inv[M],val[M]; long long ksn(long long a,int n) { long long ans=1; while(n) { if(n&1) ans=ans*a%mod; n>>=1;a=a*a%mod; } return ans; } long long zh(int a,int b) { if(b==0||a==b) return 1; return val[a]*inv[a-b]%mod*inv[b]%mod; } int n,m,t; int main(){ val[0]=inv[0]=1; for(ri i=1;i<=4e5;i++) { val[i]=val[i-1]*i%mod; } for(ri i=1;i<=4e5;i++) { inv[i]=ksn(val[i],mod-2); } read(n);read(m);read(t); while(t--) { int a,b; read(a);read(b); long long ans=0; if(a==n&&b==m){printf("0\n");continue; } if(a==n) { long long tmp=ksn(2,n+m-a-b+1); tmp=zh(a+b-1,n-1)*tmp%mod*inv[2]%mod; printf("%lld\n",tmp); } if(b==m) { long long tmp=ksn(2,n+m-a-b+1); tmp=zh(a+b-1,m-1)*tmp%mod*inv[2]%mod; printf("%lld\n",tmp); } } return 0; }View Code
后记:
- 遇到这种类型的题目可以弄一个小数据来找找规律
- 当然也要利用一些相关的算法思想
- 求组合 这个inv【i】,就是 i,但是,是代入val【i】前缀x的值!!求逆元,优化时间和空间
- 注意当某个数据错误看看数组边界,
标签:ch,cocktail,int,times,will,record,game,hearthstone,dp 来源: https://www.cnblogs.com/Lamboofhome/p/16226550.html