66-64: 模拟赛
等比数列求和
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } #define LL long long const int Mod = 1e9 + 7; LL Ksm(LL a, LL b) { LL ret = 1; while(b) { if(b & 1) ret = ret * a % Mod; a = a * a % Mod; b >>= 1; } return ret; } LL Calc(LL n, LL m) { LL Answer = 0; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= m; j ++) { (Answer += Ksm(i, j)) %= Mod; } } return Answer % Mod; } int main() { freopen("sum.in", "r", stdin); freopen("sum.out", "w", stdout); LL n, m; cin >> n >> m; LL Answer = 0; for(int i = 1; i <= n; i ++) { LL up = i * (Ksm(i, m) - 1) % Mod; LL dow = i - 1; while(up < 0) up += Mod; while(dow < 0) dow += Mod; dow = Ksm(dow, Mod - 2); (Answer += (up * dow % Mod)) %= Mod; } (Answer += m) %= Mod; while(Answer < 0) Answer += Mod; cout << Answer; return 0; }
边权和的两倍 - 距离1最远的距离
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; const int N = 5e4 + 10; #define Rep(i, a, b) for(int i = a; i <= b; i ++) #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } #define LL long long struct Node { int u, v, w, nxt; } G[N << 1]; int cnt, head[N]; int n; LL Answer; void Link(int u, int v, int w) { G[++ cnt].v = v, G[cnt].w = w, G[cnt].nxt = head[u], head[u] = cnt; } LL dis[N]; void Dfs(int u, int f) { for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v == f) continue; dis[v] = dis[u] + G[i].w; Dfs(v, u); } } int main() { freopen("tour.in", "r", stdin); freopen("tour.out", "w", stdout); n = read(); Rep(i, 1, n) head[i] = -1; Rep(i, 1, n - 1) { int u = read(), v = read(), w = read(); Link(u, v, w), Link(v, u, w); Answer += w + w; } // cout << Answer << "\n"; Dfs(1, 0); LL cut = -1; Rep(i, 1, n) cut = max(cut, dis[i]); cout << Answer - cut; return 0; }
dp + 数论
#include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <iostream> #include <vector> #include <map> using std::min; using std::max; typedef long long i64; const i64 modulo = i64(1e9) + 7; const int MaxN = 100005; const int MaxM = 1024; i64 power(i64 base, i64 k) { i64 res = 1; for ( ; k; k >>= 1) { if (k & 1) res = (res * base) % modulo; base = (base * base) % modulo; } return res; } i64 inv(i64 k) { return power(k, modulo - 2); } std::vector<i64> gen_lucky(i64 upper) { std::vector<i64> res; res.clear(); std::vector<i64> a; a.clear(); a.push_back(0); for (int i = 0; i < 10; ++i) { std::vector<i64> b; b.clear(); for (size_t j = 0; j < a.size(); ++j) { b.push_back(a[j] * 10 + 4); b.push_back(a[j] * 10 + 7); } if (b[0] < upper) { res.insert(res.end(), b.begin(), b.end()); a = b; } else { return res; } } return res; } std::vector<i64> lucky; std::map<i64, int> lucky2idx; int n, m, unlucky, k, a[MaxN], cnt[MaxM]; i64 dp[MaxM][MaxM]; i64 f[MaxN]; i64 bincoef(int a, int b) { i64 tmp = f[a]; tmp = tmp * inv(f[b]) % modulo; tmp = tmp * inv(f[a-b]) % modulo; return tmp; } int main(void) { freopen("lucky.in","r",stdin); freopen("lucky.out","w",stdout); lucky = gen_lucky(1e9); m = lucky.size(); for (int i = 0; i < m; ++i) { lucky2idx[lucky[i]] = i; } scanf("%d%d", &n, &k); unlucky = n; for (int i = 0; i < n; ++i) { scanf("%d", a+i); std::map<i64, int>::iterator it = lucky2idx.find(a[i]); if (it != lucky2idx.end()) ++cnt[it->second], --unlucky; } dp[0][0] = 1; for (int i = 0; i < m; ++i) { for (int j = 0; j <= i; ++j) { dp[i+1][j] = (dp[i+1][j] + dp[i][j]) % modulo; dp[i+1][j+1] += (dp[i+1][j+1] + (dp[i][j] * cnt[i] % modulo)) % modulo; } } f[0] = 1; for (int i = 1; i <= n; ++i) { f[i] = f[i-1] * i % modulo; } i64 ans = 0; int st = max(0, k-m); int ed = min(k, unlucky); for (int i = st; i <= ed; ++i) { ans += dp[m][k-i] * bincoef(unlucky, i) % modulo; ans %= modulo; } printf("%d\n", (int) ans); fclose(stdin); fclose(stdout); return 0; }