ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare

传送门:https://nanti.jisuanke.com/t/31453

本题是一个组合数学(DP,滑稽)题。

一个环上有N个位置,标号为1~N。设第i(1≤i≤N)个位置上的数为x[i],限制条件为:0≤x[i]<2k。另有限制条件:当位置i和位置j相邻时,x[i]⊕x[j]≠2k-1。求满足限制条件的环的状态数。

可以考虑将环切割成链,以分析问题。设:

①a[n]:长度为n,且首尾相同的满足上述条件的链的状态数;

②b[n]:长度为n,且首尾相反的满足上述条件的链的状态数;

③c[n]:长度为n,其他的满足上述条件的链的状态数。

于是,有以下转移方程:

$\begin{cases}
\ a_n=a_{n-1}+c_{n-1} \\
\ b_n=b_{n-1}+c_{n-1} \\
\ c_n=(2^k-3)c_{n-1}
\end{cases}$

可以写成矩阵乘法的形式:

$\begin{pmatrix}
a_i\\
b_i\\
c_i
\end{pmatrix}
=\begin{pmatrix}
1 & 0 & 1\\
0 & 1 & 1\\
2^k-2 & 2^k-2 & 2^k-3
\end{pmatrix}
\begin{pmatrix}
a_{i-1}\\
b_{i-1}\\
c_{i-1}
\end{pmatrix}$

初始条件:

$\begin{pmatrix}
a_1\\
b_1\\
c_1
\end{pmatrix}
=\begin{pmatrix}
2^k\\
0\\
0
\end{pmatrix}$

可以通过矩阵快速幂在O(logN)时间内求解。

答案为$ans(N,k)=(2^k-1)a_{N-1}+(2^k-2)(b_{N-1}+c_{N-1})$。

参考程序如下(实现上引用了本人编写的矩阵类的部分代码):

#include <bits/stdc++.h>
using namespace std;

const int64_t mod = 1e9 + 7;

int64_t pwr(int64_t x, int p)
{
    if (p == 0) return 1;
    if (p & 1) return x * pwr(x, p ^ 1) % mod;
    return pwr(x * x % mod, p >> 1);
}

int64_t a[3][3];

#define MAX_N 3

/***
 * Matrix is a type of 2D-array.
 * Here implements Basic Operators of Matrix.
 */
struct Matrix_t {
    int row, col;
    int64_t elem[MAX_N][MAX_N];
    Matrix_t() {}
    Matrix_t(int row, int col) : row(row), col(col) {}
    Matrix_t(int row, int col, int64_t elem[][MAX_N]) {
        this->row = row;
        this->col = col;
        if (elem != nullptr) {
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    this->elem[i][j] = elem[i][j];
                }
            }
        }
    }
    Matrix_t(const Matrix_t& obj) {
        this->row = obj.row;
        this->col = obj.col;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                this->elem[i][j] = obj.elem[i][j];
            }
        }
    }
    virtual ~Matrix_t() {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                elem[i][j] = 0;
            }
        }
        row = 0;
        col = 0;
    }
    Matrix_t& operator =(const Matrix_t& rhs) {
        row = rhs.row;
        col = rhs.col;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                elem[i][j] = rhs.elem[i][j];
            }
        }
        return *this;
    }
    //Override: Matrix Multiplication.
    Matrix_t operator *(const Matrix_t& rhs) {
        int64_t res[MAX_N][MAX_N];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < rhs.col; j++) {
                res[i][j] = 0;
                for (int k = 0; k < col; k++) {
                    res[i][j] += elem[i][k] * rhs.elem[k][j] % mod;
                    res[i][j] %= mod;
                }
            }
        }
        return Matrix_t(row, rhs.col, res);
    }
};

/***
 * Square Mairtx is a type of Matrix.
 * Here implements Integer Power of Square Matrix.
 */
struct SquareMatrix_t : Matrix_t {
    int sz;
    SquareMatrix_t() {}
    SquareMatrix_t(int sz) : Matrix_t(sz, sz), sz(sz) {}
    SquareMatrix_t(int sz, int64_t elem[][MAX_N]) : Matrix_t(sz, sz, elem), sz(sz) {}
    virtual ~SquareMatrix_t() {
        for (int i = 0; i < sz; i++) {
            for (int j = 0; j < sz; j++) {
                elem[i][j] = 0;
            }
        }
        sz = 0;
    }
    void init() {
        for (int i = 0; i < sz; i++) {
            elem[i][i] = 1;
        }
    }
    SquareMatrix_t& operator =(const Matrix_t& rhs) {
        sz = rhs.row;
        for (int i = 0; i < sz; i++) {
            for (int j = 0; j < sz; j++) {
                elem[i][j] = rhs.elem[i][j];
            }
        }
        return *this;
    }
    SquareMatrix_t operator ^(int p) {
        SquareMatrix_t res(sz);
        SquareMatrix_t tmp(*this);
        res.init();
        while (p) {
            if (p & 1) res = res * tmp;
            tmp = tmp * tmp;
            p >>= 1;
        }
        return res;
    }
};

int main(void)
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
        memset(a, 0, sizeof(a));
        int n, k;
        cin >> n >> k;
        int64_t p = pwr(2, k);
        if (n == 1) {
            cout << p << endl;
            continue;
        }
        a[0][0] = 1;
        a[0][2] = 1;
        a[1][1] = 1;
        a[1][2] = 1;
        a[2][0] = (p - 2 + mod) % mod;
        a[2][1] = (p - 2 + mod) % mod;
        a[2][2] = (p - 3 + mod) % mod;
        SquareMatrix_t mat(3, a);
        SquareMatrix_t res = mat ^ (n - 2);
        int64_t a = res.elem[0][0] * p % mod;
        int64_t b = res.elem[1][0] * p % mod;
        int64_t c = res.elem[2][0] * p % mod;
        int64_t ans = (a * ((p - 1 + mod) % mod) % mod + (b + c) % mod * ((p - 2 + mod) % mod) % mod) % mod;
        cout << ans << endl;
    }
}

原文地址:https://www.cnblogs.com/siuginhung/p/9616106.html

时间: 2024-10-05 23:25:27

ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare的相关文章

ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare (组合数学,递归)

A. Hard to prepare After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a Nogaku show during the feast. To enjoy the show, every audience has to wear a Nogaku mask, and seat around as a circle. There are

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath 做法: \[f(m,n) = \sum _{i=1}^{m} \mu(in) = \sum_{i=1}^{m}[gcd(i,n)=1]\mu(i)\mu(n) = \mu(n)\sum_{d|n}\mu(d)f(\frac{m}{d},d)\] 边界: n=1,杜教筛求\(\sum_{i=1}^{m}\mu(i)\),m = 1, 返回\(\mu(n)\),预处理尽可能把空间卡满. 2个小时的时候就推出来了这个式子,不会算复杂

ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn&#39;t want to study

262144K Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he wi

ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn&#39;t want to study (线段树)

Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he will get a

ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE

In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named "Sena" are playing a video game. The game system of this video game is quite unique: in the process of playing this game, you need to constantly fac

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the h

ICPC 2018 徐州赛区网络赛

ACM-ICPC 2018 徐州赛区网络赛 ?去年博客记录过这场比赛经历:该死的水题 ?一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进. ? ? D. Easy Math 题意: ? 给定 \(n\), \(m\) ,求 \(\sum _{i=1}^{m} \mu(in)\) .其中 $ 1 \le n \le 1e12$ , $ 1 \le m \le 2e9$ ,\(\mu(n)\) 为莫比乌斯函数. ? 思路: ? 容易知道,\(i\) 与 \(n\) 不互质时, \(\m

ACM-ICPC 2018 徐州赛区网络预赛

Rank Solved A B C D E F G H I J K 157/1526 7/11 O O ? ? . O O O O O ? O: 当场通过 ?: 赛后通过 .: 尚未通过 A Hard to prepare solved by chelly chelly's solution B BE, GE or NE solved by ch ch's solution C Cacti Lottery upsolved by chelly chelly's solution 考虑枚举*代表的

【ACM-ICPC 2018 徐州赛区网络预赛】E. End Fantasy VIX 血辣 (矩阵运算的推广)

Morgana is playing a game called End Fantasy VIX. In this game, characters have nn skills, every skill has its damage. And using skill has special condition. Briefly speaking, if this time you use skill "x", then next time you can use skill &quo