• Open judge C16H:Magical Balls 快速幂+逆元


    C16H:Magical Balls

    总时间限制: 
    1000ms
     
    内存限制: 
    262144kB
    描述

    Wenwen has a magical ball. When put on an infinite plane, it will keep duplicating itself forever.

    Initially, Wenwen puts the ball on the location (x0, y0) of the plane. Then the ball starts to duplicate itself right away. For every unit of time, each existing ball on the plane will duplicate itself, and the new balls will be put on the adjacent locations. The duplication rule of these balls is, during the i-th unit of time, a ball, which locates at (x, y), will duplicate uballs to (x, y+1), dballs to (x, y-1), lballs to (x-1, y) and rballs to (x+1, y).

    The duplication rule has a period of M. In another words, ui=ui-M, di=di-M, li=li-M, ri=ri-M, for i=M+1,M+2,...

    Wenwen is very happy because she will get many balls. It is easy to calculate how many balls she will get after N units of time. However, she wants to know the sum of x-coordinates and y-coordinates of all balls after N units of time. This is a bit difficult for her. Could you help her? Since the sum might be very large, you should give the sum modulo 1,000,000,007 to her.

    输入
    The first line contains an integer T (1 ≤ T ≤ 25), indicating the number of test cases.

    For each test case:

    The first line contains four integers N (1 ≤ N ≤ 10^18), M (1 ≤ M ≤ 20,000), x0 and y0 (-10^18 ≤ x0,y0 ≤ 10^18);

    Then follows M lines, the i-th line contains four integers: ui, di, li and ri (0 ≤ ui,di,li,ri ≤ 10,000).
    输出
    For each test case, output one integer on a single line, indicating the sum of x-coordinates and y-coordinates of all balls after N units of time, modulo 1,000,000,007.
    样例输入
    1
    2 2 1 1
    2 0 0 0
    0 0 0 1
    样例输出
    19
    提示
    In the Sample Input:

    Initially, there is 1 ball on (1,1).

    After 1 unit of time, there is 1 ball on (1,1) and 2 balls on (1,2);

    After 2 units of time, there is 1 ball on (1,1), 2 balls on (1,2), 1 ball on (2,1) and 2 balls on (2,2).
    Therefore, after 2 units of time, the sum of x-coordinates and y-coordinates of all balls is
    (1+1)*1+(1+2)*2+(2+1)*1+(2+2)*2=19.
    题意
      给你一个球 初始位置在x0,y0
      和一个周期函数
      这个周期是m天  每天向上复制Ui个球 向下复制Di个球 向左复制Li个球,向右复制Ri个球
      问你n天后 所有球的横纵坐标相加总和是多少
    题解
      Si表示第i天答案的总和, sumi 表示第i天球的总和
      S0为初始位置的答案即x+y
      设定ai = ui+ri+li+di+1 , bi = ui+ri-li-di;
      很容易得出
        Si = S0 *  (∏ai)+ ∑j ((∏ai)* bj / a[j]) ; 
      分别用逆元快速幂求解
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N = 2e5+20, M = 1e2+10, MOD = 1e9+7, inf = 2e9;
    typedef long long ll;
    
    
    ll update(ll x) {
         return  ((x % MOD)+MOD)%MOD;
    }
    
    
    ll quick_pow(ll x,ll p) {
        if(!p) return 1;
        ll ans = quick_pow(x,p>>1);
        ans = ans*ans%MOD;
        if(p & 1) ans = ans*x%MOD;
        return ans;
    }
    
    ll inv(ll x,ll mo)
    {
        return quick_pow(x,mo-2);
    }
    
    int T;
    ll n;
    ll m;
    ll U[N],D[N],R[N],L[N],A[N],B[N],Y[N];
    int main()
    {
        scanf("%d",&T);
        while(T--) {
            ll x,y;
            scanf("%lld%lld%lld%lld",&n,&m,&x,&y);
            ll S0 = (x+y )%MOD;
            ll allA = 1;
            for(int i=1;i<=m;i++) {
                scanf("%lld%lld%lld%lld",&U[i],&D[i],&L[i],&R[i]);
                A[i] = (U[i] + R[i] + L[i] + D[i] + 1 ) % MOD;
                B[i] = (U[i] + R[i] - L[i] - D[i]) % MOD;
                allA = allA * A[i] % MOD;
            }
    
            ll W = 0;
            for(int i=1;i<=m;i++) W =  (W + B[i] * inv(A[i],MOD) ) % MOD;
            //cout<<W<<endl;
            ll ans = S0 * update(quick_pow(allA, n / m)) % MOD +  update(n/m) * W % MOD * quick_pow(allA, n/m)% MOD;
            ans %= MOD;
            ll sum = quick_pow(allA,n/m);
            //cout<<ans<<" "<<sum<<endl;
            for(int i=1;i<=n%m;i++) {
                ans = (ans * (A[i]) % MOD + sum * B[i] % MOD) % MOD;
                sum = sum * (A[i]) % MOD;
            }
            printf("%lld
    ",(ans+MOD )%MOD);
    
        }
        return 0;
    }
  • 相关阅读:
    最新版 VS2015|Visual Studio Enterprise 2015简体中文版(企业版)
    MY97 日期控件只输入今天之前的值
    VARIANT类型
    C++ Struct
    MFC网络编程
    套接字编程(VC_Win32)
    套接字相关函数
    网络编程
    char str[] 与 char *str的区别详细解析
    Windows下C++多线程同步与互斥简单运用
  • 原文地址:https://www.cnblogs.com/zxhl/p/5682667.html
Copyright © 2020-2023  润新知