• HDU多校Round 7


    Solved:2

    rank:293

    J. Sequense

    不知道自己写的什么东西 以后整数分块直接用 n / (n / i)表示一个块内相同n / i的最大i

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod = 1e9 + 7;
    ll A, B, C, D, P, n;
    
    struct martix
    {
        ll c[3][3];
    };
    
    martix mul(martix A, martix B)
    {
        martix res;
        memset(res.c, 0, sizeof(res.c));
        for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++)
        for(int k = 0; k < 3; k++)
            res.c[i][j] = (res.c[i][j] + A.c[i][k] * B.c[k][j] % mod) % mod, (res.c[i][j] += mod) %= mod;
        return res;
    }
    
    martix pow_mod(martix x, ll y)
    {
        martix res;
        memset(res.c, 0, sizeof(res.c));
        res.c[0][0] = res.c[1][1] = res.c[2][2] = 1LL;
        while(y)
        {
            if(y & 1) res = mul(res, x);
            x = mul(x, x);
            y >>= 1;
        }
        return res;
    }
    
    int main()
    {
        martix og;
    
        int T;
        scanf("%d", &T);
        while(T--)    
        {
            scanf("%lld%lld%lld%lld%lld%lld", &A, &B, &C, &D, &P, &n);
            memset(og.c, 0, sizeof(og.c));
            og.c[0][0] = D + 1;
            og.c[0][1] = C - D;
            og.c[0][2] = -C;
            og.c[1][0] = og.c[2][1] = 1;
            
            
            ll f1 = A;
            ll f2 = B;
            if(n == 1)
            {
                printf("%lld
    ", A);
                continue;
            }
            if(n == 2)
            {
                printf("%lld
    ", B);
                continue;
            }
            
            if(n <= 50000)
            {
                for(int i = 3; i <= n; i++)
                {
                    ll tmp = f1 * C % mod + D * f2 % mod + P / i;
                    tmp %= mod;
                    f1 = f2;
                    f2 = tmp;
                }
                printf("%lld
    ", f2);
                continue;
            }
            
            for(int i = 3; i <= 50000; i++)
            {
                ll tmp = f1 * C % mod + D * f2 % mod + P / i;
                tmp %= mod;
                f1 = f2;
                f2 = tmp;
            }
            
            ll now = 50001;
            ll f3 = C * f1 % mod + D * f2 % mod + P / now; f3 %= mod;
            //cout<<f3<<endl;
            ll ans = f3;
            while(now < n)
            {
                if(P / now == P / n)
                {
                    ans = 0;
                    martix tmp1 = pow_mod(og, n - now);
                    ans = tmp1.c[0][0] * f3 % mod + tmp1.c[0][1] * f2 % mod; ans %= mod;
                    ans += tmp1.c[0][2] * f1 % mod; ans %= mod;
                    ans += mod; ans %= mod;
                    break;
                }
                
                if(now + 10000 >= n)
                {
                    for(int i = now + 1; i <= n; i++)
                    {
                        ll ttmp = f2 * C % mod + D * f3 % mod + P / i;
                        ttmp %= mod;
                        f1 = f2;
                        f2 = f3;
                        f3 = ttmp;
                    }
                    ans = f3;
                    break;
                }
                
                if(P / (now + 1) != P / now)
                {
                    for(int i = now + 1; i <= now + 3; i++)
                    {
                        ll tymp = f2 * C % mod + D * f3 % mod + P / i;
                        tymp %= mod;
                        f1 = f2;
                        f2 = f3;
                        f3 = tymp;
                    }
                    now += 3;
                    continue;
                }
                
                
                ll l = now, r = n;
                ll mid = l + r >> 1;
                while(l + 1 < r)
                {
                    mid = l + r >> 1;
                    if(P / mid == P / now) l = mid;
                    else r = mid;
                }
                
                ll opp;
                if(P / r == P / now) opp = r;
                else opp = l;
                
                
                if(opp - now >= 5)
                {
                    martix tmp2 = pow_mod(og, opp - now - 2);
                    ll tt = 0;
                    tt = tmp2.c[0][0] * f3 % mod + tmp2.c[0][1] * f2 % mod; tt %= mod;
                    tt += tmp2.c[0][2] * f1 % mod; tt %= mod;
                    tt += mod; tt %= mod;
                    
                    tmp2 = mul(tmp2, og);
                    ll ttt = 0;
                    ttt = tmp2.c[0][0] * f3 % mod + tmp2.c[0][1] * f2 % mod; ttt %= mod;
                    ttt += tmp2.c[0][2] * f1 % mod; ttt %= mod;
                    ttt += mod; ttt %= mod;
                    
                    f1 = tt;
                    f2 = ttt;
                    f3 = C * f1 % mod + D * f2 % mod + P / opp;
                    f3 %= mod;
                    now = opp;
                }
                else
                {
                    for(int i = now + 1; i <= opp; i++)
                    {
                        ll tmpp = C * f2 % mod + D * f3 % mod + P / i;
                        tmpp %= mod;
                        f1 = f2;
                        f2 = f3;
                        f3 = tmpp;
                    }
                    now = opp;
                }
            }
            printf("%lld
    ", ans);
        } 
        return 0;
    }
    View Code
  • 相关阅读:
    leetcode-344-反转字符串
    leetcode-136-只出现一次的数字
    leetcode-350- 两个数组的交集 II
    leetcode-36-有效的数独
    leetcode-283-移动零
    leetcode-387-字符串中的第一个唯一字符
    leetcode-242-有效的字母异位词
    HDU 2612
    Codeforces 1090B
    Codeforces 1090D
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9478851.html
Copyright © 2020-2023  润新知