zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    按钮在点击的时候,怎么取消按钮中的文本被选中
    JS观察者模式-自定义事件
    DIV中文字换行显示
    JS、CSS中的相对路径
    监听窗口大小改变,同时根据窗口大小修改某个元素的大小
    jquery中点击切换的实现
    lua_自己对“lua函数”知识点的总结
    Lua习题练习(9*9乘法表,输出所指定的图像,斐波那契数列)
    对 Lua闭包 知识点的学习的总结 ,在这里和大家分享一下,希望对大家有所帮助
    Lua的string库函数、lua中string的模式匹配
  • 原文地址:https://www.cnblogs.com/zxhl/p/5682667.html
Copyright © 2011-2022 走看看