jzoj 3857. [NOIP2014 8つの学校の入試10.4に対して最初のテストの最初の3つのゲーム]西ビラシステムは、(正規表現)を続け、

この質問は死んだ私のリズムああを再生することです。
審査キック\(T1 \)、\ (T3 \)とのみ\(30分\) そしてこの問題は、質問の非常に明確な意味を持っていないので、\(GG \)
しかし、一つは正のソリューションの後に試験を知っている場合でも、まだ少しは混乱しました。
話すことが夜のリスニングでは(実際には、ちょうど私がそれを持っているように私は感じるので、2次元配列を設定するために左に耳を傾ける)、彼らはゆっくりと)¯(¯*)に、ああ、ヤードの完了思考をクリアするために始めました。

わずか5までの要素の型のため、我々は圧力のような考えることができるように。

その後、我々は(例えば、(式)+、[要素] [要素]として、これらのタイトルの移転の方法により発現の右端から左端要素要素に行くことができる、我々は最初の要素から行くことができます第2要素)、私たちはマップを形成することができること。

セット\(F [i]が[S ] \) 行くを表す(I \)\階段状の圧力条件は、現在の要素に達する可能性があり、\(S \)を防止重複するために、計算を行うために追求プログラムの数です。
明らかに直接転送するので、私たちは前処理、他のものを必要としません。
私たちは、セット([i]の[jに\ \]) からを表す(\ I)\状態に移行(J \)\文字列をプログラムする際、この状態の同じ数を取ることができます。
状態遷移方程式が出て当然ですので:\(F [i]は、[S] = F 'へ* [S [I-1] [S]'] [S] \)
実際には、これは非常に巧妙になろう。我々が設定し、このようにしていないため、それはいくつかの魔法のものと再カウントかもしれ\(GG \) (セットアップが答えで同じ結果がでない偉大されていたとき、私はプレイしていました)

この転送のために、我々は列挙\(I \) そしてどのような同じ文字が転送されるべきであること、そして用(I \)\各要素は、我々は、それもこの文字の要素が含まれて見つけ、 、形状が状態を押下判定(S \)\、我々はあることができる([I] [Sに\ ] \) プラス\(1 \)
説明:私たちは尊重しているので(\ i)を\(\ s)は\彼らはこのような場合には追加されたのでパスは、すべて同じで、同じ文字がある、我々はこれだけの数をプログラムする必要があるので、プラス\(1 \)することができます。一方で、他の文字は、他の回でアウトになります。
この事の前処理私たちをしたら、転送が最適化するための時間を取ることができます見つけることができます。

コード

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 510
#define mo 4294967296ll
#define ll long long
#define mem(x, a) memset(x, a, sizeof x)
#define mpy(x, y) memcpy(x, y, sizeof y)
#define fo(x, a, b) for (int x = (a); x <= (b); x++)
#define fd(x, a, b) for (int x = (a); x >= (b); x--)
#define go(x) for (int p = tail[x], v; p; p = e[p].fr)
using namespace std;
int n, len, ys[7][27], tot = 0;
int ke[80], cf[7], gs[7], z[7], top = 0, gt[27];
ll f[80][80], c[80][80], to[80][80], ans = 0;
char s[N];

template<typename T>
inline void read(T& x)
{
    x = 0; int f = 0; char c = getchar();
    while (c < '0' || c > '9') f = (c == '-') ? 1 : f, c = getchar();
    while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    if (f == 1) x = -x;
}

ll gsc(ll x, ll y)
{
    ll s = 0;
    while (y)
    {
        if (y & 1) s = (s + x) % mo;
        x = (x + x) % mo, y >>= 1;
    }
    return s;
}

int main()
{
    freopen("regex.in", "r", stdin);
    freopen("regex.out", "w", stdout);
    scanf("%s%d", s + 1, &n);
    len = strlen(s + 1);
    cf[0] = 1; fo(i, 1, 6) cf[i] = cf[i - 1] << 1;
    fo(i, 1, len)
    {
        if (s[i] == '[')
        {
            i++, tot++, ke[tot - 1] |= cf[tot - 1];
            while (s[i] != ']') gs[tot]++, ys[tot][s[i] - 'a'] = 1, i++;
        }
        else if (s[i] == '(') z[++top] = tot + 1;
        else if (s[i] == ')') ke[tot] |= cf[z[top] - 1], top--;
    }
    fo(i, 1, cf[tot] - 1)
    {
        mem(gt, 0);
        fo(j, 1, tot)
        {
            if (! (i & cf[j - 1])) continue;
            fo(k, 1, tot)
            {
                if (! (ke[j] & cf[k - 1])) continue;
                fo(l, 0, 25) if (ys[k][l]) gt[l] |= cf[k - 1];
            }
        }
        fo(j, 0, 25) to[i][gt[j]]++;
    }
    f[1][1] = gs[1], n--;
    while (n)
    {
        if (n & 1)
        {
            mem(c, 0);
            fo(k, 1, cf[tot] - 1)
                fo(j, 1, cf[tot] - 1)
                    (c[1][j] += gsc(f[1][k], to[k][j]) % mo) %= mo;
            mpy(f, c);
        }
        mem(c, 0);
        fo(k, 1, cf[tot] - 1)
            fo(i, 1, cf[tot] - 1)
                fo(j, 1, cf[tot] - 1)
                    (c[i][j] += gsc(to[i][k], to[k][j]) % mo) %= mo;
        mpy(to, c);
        n >>= 1;
    }
    fo(i, 1, cf[tot] - 1)
        if (i & cf[tot - 1]) ans += f[1][i];
    printf("%lld\n", ans % mo);
    return 0;
}

おすすめ

転載: www.cnblogs.com/jz929/p/12210329.html