index > 牛客多校第五場
題號 | 標題 | 通過率 | 做法 | 狀態 |
---|---|---|---|---|
A | digits 2 | 1017/2383 | 簽到 | √+ |
B | generator 1 | 555/3660 | 矩陣快速冪/十進制優化 | ○ |
C | generator 2 | 37/626 | ||
D | generator 3 | 4/23 | ||
E | independent set 1 | 45/110 | ||
F | maximum clique 1 | 93/838 | ||
G | subsequence 1 | 522/2513 | dp | √- |
H | subsequence 2 | 286/1366 | ||
I | three points 1 | 139/2701 | ||
J | three points 2 | 7/76 |
○
代表賽後補題√+
代表賽內我通過的√-
代表賽內不是我做的√-○
代表賽內不是我做的,補了
A - digits 2
好像我們腦子也不是轉得很快,所以還是廢了點功夫纔想到拼接。
B - generator 1
比賽時莫名其妙地以爲,矩陣乘法也可以歐拉降冪。然後從頭wa到結束。
其實用了一個很巧妙的想法。
題意就是給一個公式(顯然是用二維矩陣快速冪求的)。然後給你一個無比龐大的n()。但是個數存不下來,轉二進制又非常麻煩。
那麼咋辦?可以直接用十進制來做呀,我們回顧一下二進制快速冪就是取二進制每一位是1的時候,把乘冪處理好的底數乘上去。由於二進制每位只有兩個選擇,所以比較簡單。
十進制也完全可以處理底數,但是二進制每一位還有9個選擇,那也好辦,如果這一位是,。
這樣的每次乘冪的次數就降低到以下了,這個乘冪還是有必要二進制快速冪一下,這題卡這個是嚴了一點。但是這樣也避免了全局轉二進制太麻煩,而且複雜度也不至於太高。
#define _debug(x) cerr<<#x<<" = "<<x<<endl
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename _Tp, const int MAXMatrixSize>
struct Matrix {
_Tp m[MAXMatrixSize][MAXMatrixSize];
_Tp mod = 0;
Matrix() {
memset(m, 0, sizeof m);
}
Matrix(int _mod) : mod(_mod) {
memset(m, 0, sizeof m);
}
void init1() {
//*this = Matrix(mod);
set(0, 0, 1);
set(1, 1, 1);
// for (int i = 0; i < MAXMatrixSize; i++)
// m[i][i] = 1;
}
inline void set(const int &r, const int &c, const _Tp &v) { this->m[r][c] = v; }
inline _Tp get(const int &r, const int &c) { return this->m[r][c]; }
inline void setMod(const _Tp &_mod) { this->mod = _mod; }
inline Matrix operator*(const Matrix t) {
Matrix res(mod);//= Matrix(mod);
res.setMod(mod);
for (int i = 0; i < MAXMatrixSize; i++)
for (int j = 0; j < MAXMatrixSize; j++)
for (int k = 0; k < MAXMatrixSize; k++)
res.m[i][j] = (res.m[i][j] + m[i][k] * t.m[k][j]) % mod;
return res;
}
};
typedef Matrix<ll, 2> mat;
mat A, B;
ll x0, x1, a, b;
ll mo, len;
char n[1000059];
inline mat fpow(mat base, ll exp) {
mat res(mo);
res.init1();
while (exp) {
if (exp & 1)res = res * base;
exp >>= 1;
base = base * base;
}
return res;
}
inline ll calc() {
len = strlen(n);
//reverse(n, n + len);
mat res(mo);
res.init1();
mat base = B;
for (int i = len - 1; i >= 0; --i) {
if (n[i] > '0')
res = res * fpow(base, n[i] - '0');
base = fpow(base, 10);
}
res = A * res;
return res.get(0, 0);
}
int main() {
scanf("%lld%lld%lld%lld", &x0, &x1, &a, &b);
scanf("%s %lld", n, &mo);
A = mat(mo);
A.set(0, 0, x0);
A.set(0, 1, x1);
B = mat(mo);
B.set(0, 0, 0);
B.set(0, 1, b);
B.set(1, 0, 1);
B.set(1, 1, a);
printf("%lld\n", calc());
return 0;
}
/*
* */