"ZJOI2011" rapid cell matrix power

Meaning of the questions:

Input:

It contains two lines, in which:

Conduct a first positive integer \ (n-\) , represents the length of the cell password.

The second row co \ (n-\) numbers, the password for a given cell, with no spaces.

Output:

It contains only an integer number of types of cells \ (mod 1000000007 \) Results

Ideas:

For the first division, method cut if different, then splitting out of the ball is different, so do not cut out to consider the same situation have an impact on the results of the second division.

Different means:

1, the number of splinter different ball

2, the same number but different mass distribution

Proof, consider the section of the password cells \ (ABCD \) dividing the like in place, it can be demonstrated by contradiction like

In fact when the examination can venture to guess the emotional prove ×

For the second division and differentiation problem can be transformed into, there \ (x \) balls, \ (the X--1 \) a filament, to choose some of the degradation satisfy adjacent must have at least a degenerate. Can be defined \ (DP \) state, \ (DP [I] [0] \) represents \ (I \) th not degraded, \ (DP [I] [. 1] \) said degradation, it can be get two equations:

dp[i][0]=dp[i-1][1]
dp[i][1]=dp[i-1][0]+dp[i-1][1]

This formula is actually above the Fibonacci column, the problem is transformed into seeking Fibonacci column \ (x-1 \) position, quickly find Fibonacci matrix lists the rapid power of writing.

Q can be selected for the second position of the current cut to enumerate \ (I \) , the last position \ (J \) , \ (ANS [I] = \ sum_ {J ^ = {I}. 1. 1- } \, ans [j] * val [j + 1] [i] \)

But \ (val [j + 1] [i] \) will be large, high-precision write will have problems, then we can change ideas, set matrix \ (k \) .

For \ (ij of \) contribution in the interval \ (^ {K Val [I] [J]} \) , then the conversion equation has \ (k ^ {val [i ] [j]} = (k ^ {val [i] [j -1]}) ^ {10} * k ^ {s [j] - '0'} \)

Recursive come this way, every time we use only multiplied by the last one, so it can be pretreated with the above equation \ (val [i] [j ] \)

Code:

#include<bits/stdc++.h>
#define M 1005
#define ll long long
#define Mod 1000000007
using namespace std;
int n;
char s[M];
struct P2 {
    struct node {
        ll a[2][2];
        node() {
            memset(a,0,sizeof(a));
        }
        node operator*(const node&_)const {
            node res;
            for(int i=0; i<2; i++)
                for(int j=0; j<2; j++)
                    for(int k=0; k<2; k++)
                        res.a[i][k]=(res.a[i][k]+a[i][j]*_.a[j][k]%Mod)%Mod;
            return res;
        }
        void operator+=(const node&_) {
            for(int i=0; i<2; i++)
                for(int j=0; j<2; j++)
                    a[i][j]=(a[i][j]+_.a[i][j])%Mod;
        }
    } val[1005][1005],dp[1005],w;
    node mul(node a,int y) {
        node res;
        res.a[0][0]=res.a[1][1]=1;
        while(y) {
            if(y&1)res=res*a;
            a=a*a,y>>=1;
        }
        return res;
    }
    void solve() {
        w.a[0][0]=0,w.a[0][1]=1,w.a[1][0]=1,w.a[1][1]=1;//初始化矩阵
        for(int i=1; i<=n; i++) {
            val[i][i]=mul(w,s[i]-'0');
            for(int j=i+1; j<=n; j++)
                val[i][j]=mul(val[i][j-1],10)*mul(w,s[j]-'0');
        }
        for(int i=1; i<=n; i++) {
            dp[i]=val[1][i];
            for(int j=1; j<i; j++)
                dp[i]+=dp[j]*val[j+1][i];
        }
        printf("%lld\n",dp[n].a[0][0]);
    }
} p2;
int main() {
    scanf("%d%s",&n,s+1);
    p2.solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/cly1231/p/11355825.html