Arithmetic of Bomb 2 题解

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6145

我们考虑记下状态a+b*c

那么考虑一个非括号与'#'的字符,如果是一个数字,那么显然变成a+b*(c*10+d)

如果是乘号,那么显然a+(b*c)*0

如果是加号,那么是(a+b*c)+1*0

如果是减号,那么是(a+b*c)-1*0

我们发现a,b,b*c,1的变换是线性的,可以用矩阵维护

//waz
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)((x).size()))

typedef pair<int, int> PII;
typedef vector<int> VI;
typedef long long int64;
typedef unsigned int uint;
typedef unsigned long long uint64;

#define gi(x) ((x) = F())
#define gii(x, y) (gi(x), gi(y))
#define giii(x, y, z) (gii(x, y), gi(z))

int F()
{
    char ch;
    int x, a;
    while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
    if (ch == '-') ch = getchar(), a = -1;
    else a = 1;
    x = ch - '0';
    while (ch = getchar(), ch >= '0' && ch <= '9')
        x = (x << 1) + (x << 3) + ch - '0';
    return a * x;
}

const int mod = 1e9 + 7;

int inc(int a, int b) { a += b; return a >= mod ? a - mod : a; }

int dec(int a, int b) { a -= b; return a < 0 ? a + mod : a; }

struct matrix
{
    int a[4][4];
    matrix() { memset(a, 0, sizeof a); }
    friend matrix operator * (matrix a, matrix b)
    {
        matrix c;
        for (int k = 0; k < 4; ++k)
            for (int i = 0; i < 4; ++i)
                for (int j = 0; j < 4; ++j)
                    c.a[i][j] = inc(c.a[i][j], 1LL * a.a[i][k] * b.a[k][j] % mod);
        return c;
    }
} MUL, INC, DEC, beg, I;

matrix ADD(int d)
{
    matrix ret;
    ret.a[0][0] = 1;
    ret.a[1][1] = 1;
    ret.a[2][2] = 10;
    ret.a[3][3] = 1;
    ret.a[1][2] = d;
    return ret;
}

matrix calc(char *s, int l, int r)
{
    matrix ret = I;
    for (int i = l; i <= r; ++i)
    {
        if (s[i] >= '0' && s[i] <= '9')
            ret = ret * ADD(s[i] - '0');
        else if (s[i] == '*')
            ret = ret * MUL;
        else if (s[i] == '+')
            ret = ret * INC;
        else if (s[i] == '-')
            ret = ret * DEC;
    }
    return ret;
}

matrix power(matrix a, long long x)
{
    matrix ret = I;
    for (; x; x >>= 1)
    {
        if (x & 1) ret = ret * a;
        a = a * a;
    }
    return ret;
}

const int N = 3e5 + 10; 

int main()
{
    I.a[0][0] = I.a[1][1] = I.a[2][2] = I.a[3][3] = 1;
    beg.a[0][1] = beg.a[0][3] = 1;
    MUL.a[0][0] = 1;
    MUL.a[2][1] = 1;
    MUL.a[3][3] = 1;
    INC.a[0][0] = 1;
    INC.a[2][0] = 1;
    INC.a[3][1] = 1;
    INC.a[3][3] = 1;
    DEC.a[0][0] = 1;
    DEC.a[2][0] = 1;
    DEC.a[3][1] = mod - 1;
    DEC.a[3][3] = 1;
    int T;
    gi(T);
    while (T--)
    {
        static char str[N];
        scanf("%s", str + 1);
        int n = strlen(str + 1);
        matrix c = beg;
        for (int i = 1; i <= n; ++i)
        {
            if (str[i] == '(')
            {
                int j = i + 1;
                while (str[j] != ')') ++j;
                matrix t = calc(str, i, j - 1);
                j += 3;
                long long x = 0;
                while (str[j] != ')') x = x * 10 + str[j] - '0', ++j;
                i = j;
                c = c * power(t, x);
            }
            else c = c * calc(str, i, i);
        }
        printf("%d\n", inc(c.a[0][0], c.a[0][2]));
    }
}

 

posted @ 2019-03-02 15:04  AnzheWang  阅读(198)  评论(0编辑  收藏  举报