codeforces#575A——Fibonotci

来源:互联网 发布:java程序异常处理 编辑:程序博客网 时间:2024/05/29 17:58

1、题意:fibonotci序列定义为下:
F[n]=s[n1]F[n1]+s[n2]F[n2](n>=2)
F[0]=0,F[1]=1
其中s是一个循环长度为n的循环数组,即满足s[i]=s[i
不过,s这个数组被熊孩子修改了几个位置,他把s中的第j个位置修
改为了vj,也就是说,对于位置j,s[j]=v[j](j>=n)
请你在熊孩子修改之后,求出F[k]对P取模的结果。
2、分析:这道题是HLOI2016的day1T2,思考,我们可以直接采用矩阵乘法,那么有这些破坏点,首先不考虑破坏点,我们可以考虑纯循环的状态下我们怎么计算,算出单独一个循环的矩阵,怎么算呢?直接暴力的将每一步转移矩阵乘起来就好了嘛= =然后零头,就用线段树查询区间积就好了,然后整个算法是O(nlogk)的,细节好多TAT

#include <map>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define M 1000010#define LL long longinline LL read(){    char ch = getchar(); LL x = 0, f = 1;    while(ch < '0' || ch > '9'){        if(ch == '-') f = -1;        ch = getchar();    }    while('0' <= ch && ch <= '9'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * f;}LL n, K, P;struct matrix{    LL a[2][2];    matrix(){        memset(a, 0, sizeof(a));    }    inline bool operator == (const matrix& rhs) const{        return a[0][0] == rhs.a[0][0] && a[0][1] == rhs.a[0][1] && a[1][0] == rhs.a[1][0] && a[1][1] == rhs.a[1][1];    }    inline bool operator != (const matrix& rhs) const{        return !(*this == rhs);    }     inline matrix operator * (const matrix& rhs) const{        matrix ret;        for(int i = 0; i <= 1; i ++){            for(int j = 0; j <= 1; j ++){                for(int k = 0; k <= 1; k ++){                    ret.a[i][j] += a[i][k] * rhs.a[k][j];                }                ret.a[i][j] %= P;            }        }         return ret;    }    inline void print(){        for(int i = 0; i <= 1; i ++){            for(int j = 0; j <= 1; j ++){                printf("%d", a[i][j]);            }             puts("");        }    }};matrix null;inline matrix power(matrix A, LL B){    matrix ret;    ret.a[0][0] = 1; ret.a[1][1] = 1;    while(B){        if(B & 1) ret = ret * A;        A = A * A;        B >>= 1;    }    return ret;}inline matrix get_matrix(LL a, LL b){    matrix ret;    ret.a[1][0] = 1;    ret.a[0][1] = a;    ret.a[1][1] = b;    return ret;} map<LL, LL> spe;LL s[M];inline LL get_val(LL x){    if(spe.count(x)) return spe[x];    return s[x % n];}matrix q[M];inline void build(int l, int r, int o){    if(l == r){        q[o] = get_matrix(s[l], s[l + 1]);        return;    }    int mid = (l + r) / 2;    build(l, mid, 2 * o);    build(mid + 1, r, 2 * o + 1);    q[o] = q[2 * o] * q[2 * o + 1];}inline matrix query(int l, int r, int o, int x, int y){    if(x <= l && r <= y){        return q[o];    }    int mid  = (l + r) / 2;    matrix ls, rs;    if(x <= mid) ls = query(l, mid, 2 * o, x, y);    if(y > mid) rs = query(mid + 1, r, 2 * o + 1, x, y);    if(ls != null && rs != null) return ls * rs;    return ls != null ? ls : rs;}pair<LL, matrix> abnormal[M];int tot;inline matrix getans(LL l, LL r){    matrix ret;    if(r - l >= n){        LL k = (r - l) / n, st = (r - l) % n;        matrix A = query(0, 2 * n - 1, 1, l % n, l % n + n - 1);        ret = power(A, k);        if(st) ret = ret * query(0, 2 * n - 1, 1, r % n + n - st, r % n + n - 1);     }    else{        if(l % n < r % n) ret = query(0, 2 * n - 1, 1, l % n, r % n - 1);        else ret = query(0, 2 * n - 1, 1, l % n, r % n + n - 1);    }    return ret;}int main(){    //freopen("fibonotci.in", "r", stdin);    //freopen("fibonotci.out", "w", stdout);    K = read(), P = read();    if(P == 1){        return puts("0"), 0;    }     //puts("fuck");    n = read();    for(int i = 0; i < n; i ++){        s[i] = read(); s[i + n] = s[i];    }    s[2 * n] = s[0];    build(0, 2 * n - 1, 1);    int m = read();    for(int i = 1; i <= m; i ++){        LL u = read(), v = read();        spe[u] = v;    }    tot = -1;    for(map<LL, LL> :: iterator it = spe.begin(); it != spe.end(); it ++){        if(!(tot && abnormal[tot].first == it -> first - 1)){            if(it -> first - 1 < K - 1){                abnormal[++ tot] = make_pair(it -> first - 1, get_matrix(get_val(it -> first - 1), it -> second));            }        }        if(it -> first < K - 1){            abnormal[++ tot] = make_pair(it -> first, get_matrix(it -> second, get_val(it -> first + 1)));        }    }    if(K){        abnormal[++ tot] = make_pair(K - 1, get_matrix(get_val(K - 1), get_val(K)));    }    matrix cur;    cur.a[0][0] = 1; cur.a[1][1] = 1;    //cur.print();    //printf("%d\n", tot);    for(int i = 0; i <= tot; i ++){        //printf("%d\n", abnormal[i].first);        LL last = i ? abnormal[i - 1].first + 1 : 0ll;        if(abnormal[i].first > last){            cur = cur * getans(last, abnormal[i].first);        }        cur = cur * abnormal[i].second;    //  cur.print();    }    printf("%d\n", cur.a[1][0]);    return 0;}
0 0