2016-2017 ACM-ICPC Asia-Bangkok Regional Contest

Posted hetui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016-2017 ACM-ICPC Asia-Bangkok Regional Contest相关的知识,希望对你有一定的参考价值。

G:矩阵快速幂

首先找规律,发现数量规律是一个斐波拉契数列,长度为k的串,长度为f(k+1)。之后求[L,R]区间内的和,于是可以想到利用矩阵快速幂求前缀和,将2*2的斐波拉契数列系数矩阵增加一维求和。注意初始的是f(k+1)。所以构造矩阵有一些奇特(见代码)

技术分享图片
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
using namespace std;
const long long mod = 1e9 + 7;
struct Matrix
{
    long long data[35][35];
    int col, row;
    Matrix() {}
    Matrix(int _row, int _col)
    {
        row = _row;
        col = _col;
        memset(data, 0, sizeof(data));
    }
    const long long * operator [] (int row) const         //жидиЯТБъдЫЫуЗ?
    {
        return data[row];
    }
    long long * operator [] (int row)
    {
        return data[row];
    }
};
Matrix operator * (const Matrix &m1, const Matrix &m2)
{
    Matrix ans_met(m1.row, m2.col);
    int i, j, k;
    for (i = 0; i < m1.row; i++)
    {
        for (j = 0; j < m2.col; j++)
        {
            for (k = 0; k < m1.col; k++)
            {
                ans_met[i][j] = (ans_met[i][j] + (m1[i][k] * m2[k][j]) % mod) % mod;
            }
        }
    }
    return ans_met;
}
Matrix operator ^(const Matrix &mm, long long q)
{
    Matrix ans_met(mm.row, mm.col);
    Matrix ret(mm.row, mm.col);
    int i, j;
    for (i = 0; i < ans_met.row; i++)
    {
        for (j = 0; j < ans_met.col; j++) ret[i][j] = mm[i][j];
        ans_met[i][i] = 1;
    }
    while (q > 0)
    {
        if (q % 2 == 1) ans_met = ans_met * ret;
        ret = ret * ret;
        q /= 2;
    }
    return ans_met;
}
Matrix operator + (const Matrix &m1, const Matrix &m2)
{
    Matrix ans_met(m1.row, m2.col);
    int i, j;
    for (i = 0; i < m1.row; i++)
    {
        for (j = 0; j < m1.col; j++)
        {
            ans_met[i][j] = (m1[i][j] + m2[i][j]) % mod;
        }
    }
    return ans_met;
}

Matrix fab(2, 2), mat(3, 3);

long long solve(long long q)
{
    q++;              //注意要移位
    Matrix tmp(3, 3);
    tmp = mat ^ q;
    return tmp[0][2]-1;
}

int main()
{
    int i, j;
    int t;
    scanf("%d", &t);
    int cases = 1;
    while (t--)
    {
        long long l, r, k;
        scanf("%lld%lld%lld", &l, &r, &k);
        if (l%k != 0) l += k - (l%k);      //处理余数
        if (r%k != 0) r -= r % k;
        fab[0][0] = 1;
        fab[0][1] = 1;
        fab[1][0] = 1;
        fab[1][1] = 0;
        fab = fab ^ k;

        mat[0][0] = fab[0][0];         //构造求和矩阵
        mat[0][1] = fab[0][1];
        mat[1][0] = fab[1][0];
        mat[1][1] = fab[1][1];
        mat[0][2] = 1;
        mat[1][2] = 1;
        mat[2][0] = 0;
        mat[2][1] = 0;
        mat[2][2] = 1;
        long long le = solve(l / k - 1), ri = solve(r / k);
        long long ans = ((ri - le) % mod + mod) % mod;
        printf("Case %d: ", cases++);
        printf("%d
", ans);
    }
    return 0;
}
View Code

 

以上是关于2016-2017 ACM-ICPC Asia-Bangkok Regional Contest的主要内容,如果未能解决你的问题,请参考以下文章

2016-2017 ACM-ICPC CHINA-Final Solution

2016-2017 ACM-ICPC CHINA-Final 个人题解

2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016) 个人题解

2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)

2016-2017 ACM-ICPC Asia-Bangkok Regional Contest

2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution