BestCoder Round #8
A:签到题不多说
B:矩阵快速幂,奇数项的式子为f(n) = 4 * f(n - 1) + 1,偶数项是奇数项的两倍,然后构造矩阵为4 1 0 1进行快速幂即可
C:dp+树状数组加速,dp[i][j]表示以i为结尾长度为j的种数,然后把数字离散化掉,每次状态转移都需要从前一个区间和转移过来,所以可以利用树状数组维护
代码:
A:
#include <cstdio> #include <cstring> #include <algorithm> #include <set> using namespace std; typedef long long ll; ll num[105]; set<ll> save; int n; int main() { while (~scanf("%d", &n)) { save.clear(); for (int i = 0; i < n; i++) { scanf("%I64d", &num[i]); for (int j = 0; j < i; j++) { save.insert(num[i] + num[j]); } } ll ans = 0; for (set<ll>::iterator it = save.begin(); it != save.end(); it++) { ans += *it; } printf("%I64d\n", ans); } return 0; }
B:
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> using namespace std; typedef long long ll; ll n, m; struct mat { ll v[2][2]; mat() {memset(v, 0, sizeof(v));} mat operator * (mat c) { mat ans; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { ans.v[i][j] = (ans.v[i][j] + v[i][k] * c.v[k][j]) % m; } } } return ans; } }; mat pow_mod(mat A, ll k) { mat ans; for (int i = 0; i < 2; i++) ans.v[i][i] = 1; while (k) { if (k&1) ans = ans * A; A = A * A; k >>= 1; } return ans; } int main() { while (cin >> n >> m) { mat A; A.v[0][0] = 4; A.v[0][1] = 1; A.v[1][0] = 0; A.v[1][1] = 1; A = pow_mod(A, (n + 1) / 2); ll ans = A.v[0][1]; ans %= m; if (n % 2 == 0) ans = ans * 2 % m; cout << ans << endl; } return 0; }
C:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lowbit(x) (x&(-x)) const int N = 10005; const int M = 105; const int MOD = 123456789; int n, m, dp[N][M], bit[105][N]; void add(int *bit, int x, int v) { while (x < N) { bit[x] = (bit[x] + v) % MOD; x += lowbit(x); } } int get(int *bit, int x) { int ans = 0; while (x) { ans = (ans + bit[x]) % MOD; x -= lowbit(x); } return ans; } struct Num { int val, rank, id; } num[N]; bool cmpid(Num a, Num b) { return a.id < b.id; } bool cmpval(Num a, Num b) { return a.val < b.val; } int main() { while (~scanf("%d%d", &n, &m)) { memset(bit, 0, sizeof(bit)); for (int i = 1; i <= n; i++) { scanf("%d", &num[i].val); num[i].id = i; } sort(num + 1, num + n + 1, cmpval); num[1].rank = 2; for (int i = 2; i <= n; i++) { num[i].rank = num[i - 1].rank; if (num[i].val > num[i - 1].val) num[i].rank++; } sort(num + 1, num + n + 1, cmpid); add(bit[0], 1, 1); memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = min(m, i); j >= 1; j--) { int tmp = get(bit[j - 1], num[i].rank - 1); dp[i][j] = (dp[i][j] + tmp) % MOD; add(bit[j], num[i].rank, tmp); } } int ans = 0; for (int i = 1; i <= n; i++) ans = (ans + dp[i][m]) % MOD; printf("%d\n", ans); } return 0; }
时间: 2024-11-16 12:17:20