1. 程式人生 > 其它 >cocktail with hearthstone(組合數+找規律+一點點的dp思想+快速冪)

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的值!!求逆元,優化時間和空間
  • 注意當某個資料錯誤看看陣列邊界,