水题放送,写得依旧丑:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const int INF = 2e9 + 2333; 9 typedef long long ll; 10 typedef pair<int, int> P; 11 int H, G; 12 ll f[1005][1005][2]; 13 int dishg[1005][1005]; 14 int dish[1005], disg[1005]; 15 vector<P> hh, gg; 16 17 int sqr(int x) { 18 return x * x; 19 } 20 21 int dis(vector<P> v1, int i, vector<P> v2, int j) { 22 return sqr(v1[i].first - v2[j].first) + sqr(v1[i].second - v2[j].second); 23 } 24 25 void init() { 26 for (int i = 1; i <= H; i++) 27 for (int j = 1; j <= G; j++) 28 dishg[i][j] = dis(hh, i, gg, j); 29 f[1][0][1] = INF; 30 for (int i = 2; i <= H; i++) { 31 dish[i] = dis(hh, i-1, hh, i); 32 f[i][0][0] = f[i-1][0][0] + dish[i]; 33 f[i][0][1] = INF; 34 } 35 for (int j = 1; j <= G; j++) { 36 disg[j] = dis(gg, j-1, gg, j); 37 f[0][j][1] = INF; 38 f[0][j][0] = INF; 39 } 40 } 41 42 ll dp() { 43 for (int i = 1; i <= H; i++) { 44 for (int j = 1; j <= G; j++) { 45 ll a = min(f[i-1][j][0] + dish[i], f[i-1][j][1] + dishg[i][j]); 46 ll b = min(f[i][j-1][0] + dishg[i][j], f[i][j-1][1] + disg[j]); 47 f[i][j][0] = a; 48 f[i][j][1] = b; 49 } 50 } 51 return f[H][G][0]; 52 } 53 54 int main() { 55 scanf("%d%d", &H, &G); 56 hh.push_back(P(0, 0)); 57 gg.push_back(P(0, 0)); 58 for (int i = 1; i <= H; i++) { 59 int x, y; 60 scanf("%d%d", &x, &y); 61 hh.push_back(P(x, y)); 62 } 63 for (int i = 1; i <= G; i++) { 64 int x, y; 65 scanf("%d%d", &x, &y); 66 gg.push_back(P(x, y)); 67 } 68 init(); 69 printf("%lld\n", dp()); 70 return 0; 71 }
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const int INF = 2e9 + 2333; 9 typedef long long ll; 10 typedef pair<int, int> P; 11 int N, H, Delta; 12 int f[2005][2005], eat[2005][2005]; 13 int pos1[2005]; 14 15 int dp() { 16 for (int i = 1; i <= H; i++) { 17 int maxx = 0; 18 for (int j = 1; j <= N; j++) { 19 f[i][j] = f[i-1][j]; 20 if (i > Delta) { 21 int t = i - Delta; 22 f[i][j] = max(f[i][j], f[t][pos1[t]]); 23 } 24 f[i][j] += eat[j][i]; 25 if (f[i][j] > maxx) { 26 maxx = f[i][j]; 27 pos1[i] = j; 28 } 29 } 30 } 31 int ans = 0; 32 for (int i = 1; i <= N; i++) 33 ans = max(ans, f[H][i]); 34 return ans; 35 } 36 37 int main() { 38 scanf("%d%d%d", &N, &H, &Delta); 39 for (int i = 1; i <= N; i++) { 40 int ni, pos; 41 for (scanf("%d", &ni); ni; ni--) { 42 scanf("%d", &pos); 43 eat[i][pos]++; 44 } 45 } 46 printf("%d\n", dp()); 47 return 0; 48 }
1 #include <bits/stdc++.h> 2 #define ri readint() 3 #define gc getchar() 4 #define ls p << 1 5 #define rs p << 1 | 1 6 using namespace std; 7 8 typedef long long ll; 9 const int maxn = 100005; 10 int n, m; 11 struct Seg { 12 int l, r; 13 bool fixed; 14 ll sum; 15 }t[maxn << 2]; 16 17 inline int readint() { 18 int x = 0, s = 1, c = gc; 19 while (c <= 32) c = gc; 20 if (c == '-') s = -1, c = gc; 21 for (; isdigit(c); c = gc) 22 x = x * 10 + c - 48; 23 return x * s; 24 } 25 26 void build(int l, int r, int p) { 27 t[p].l = l, t[p].r = r; 28 if (l == r) { 29 t[p].sum = ri; 30 t[p].fixed = t[p].sum <= 1ll; 31 return; 32 } 33 int mid = (l + r) >> 1; 34 build(l, mid, ls); 35 build(mid+1, r, rs); 36 t[p].sum = t[ls].sum + t[rs].sum; 37 t[p].fixed = t[ls].fixed && t[rs].fixed; 38 } 39 40 void Update(int l, int r, int p) { 41 if (t[p].fixed) return; 42 if (t[p].l == t[p].r) { 43 t[p].sum = sqrt(t[p].sum); 44 t[p].fixed = t[p].sum <= 1ll; 45 return; 46 } 47 int mid = (t[p].l + t[p].r) >> 1; 48 if (l <= mid) Update(l, r, ls); 49 if (mid < r) Update(l ,r, rs); 50 t[p].sum = t[ls].sum + t[rs].sum; 51 t[p].fixed = t[ls].fixed && t[rs].fixed; 52 } 53 54 ll Query(int l, int r, int p) { 55 if (l <= t[p].l && t[p].r <= r) 56 return t[p].sum; 57 int mid = (t[p].l + t[p].r) >> 1; 58 ll res = 0ll; 59 if (l <= mid) res += Query(l, r, ls); 60 if (mid < r) res += Query(l, r, rs); 61 return res; 62 } 63 64 int main() { 65 n = ri; 66 build(1, n, 1); 67 for (m = ri; m; m--) { 68 int x = ri, l = ri, r = ri; 69 if (x == 1) { 70 printf("%lld\n", Query(l, r, 1)); 71 } else { 72 Update(l, r, 1); 73 } 74 } 75 return 0; 76 }
cf818E,计数不一定非要乘法原理,枚举标杆累加。此题性质符合尺取,l和r可不断后移。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1e5 + 5; 5 int n, k, a[maxn]; 6 int pri[55], cnt[55], t; 7 int b[maxn][55]; 8 9 void div(int k) { 10 for (int i = 2; i * i <= k; i++) { 11 if (k % i == 0) { 12 pri[++t] = i; 13 while (k % i == 0) { 14 k /= i; 15 cnt[t]++; 16 } 17 } 18 } 19 if (k > 1) { 20 pri[++t] = k; 21 cnt[t] = 1; 22 } 23 } 24 25 long long two_point() { 26 int l = 1, r = 0; 27 long long ans = 0; 28 while (l <= n) { 29 bool valid = false; 30 while (r < n && !valid) { 31 r++; 32 valid = true; 33 for (int j = 1; j <= t; j++) 34 valid &= (b[r][j] - b[l-1][j]) >= cnt[j]; 35 } 36 if (!valid) break; 37 while (l <= r && valid) { 38 ans += n - r + 1; 39 l++; 40 for (int j = 1; j <= t; j++) 41 valid &= (b[r][j] - b[l-1][j]) >= cnt[j]; 42 } 43 } 44 return ans; 45 } 46 47 int main() { 48 scanf("%d%d", &n, &k); 49 div(k); 50 for (int i = 1; i <= n; i++) { 51 scanf("%d", &a[i]); 52 for (int j = 1; j <= t; j++) { 53 while (a[i] % pri[j] == 0) { 54 a[i] /= pri[j]; 55 b[i][j]++; 56 } 57 b[i][j] += b[i-1][j]; 58 } 59 } 60 cout << two_point() << endl; 61 return 0; 62 }
cf818F,我强猜一下结论的原因:难道是因为完全图边多、链桥多,所以边多桥多就凑一起?
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 int q; 6 ll n; 7 8 ll judge(ll k) { 9 return n - k + min(n - k, (k*k - k) / 2); 10 } 11 12 int main() { 13 ios_base::sync_with_stdio(false); 14 cin.tie(0); 15 for (cin >> q; q; q--) { 16 cin >> n; 17 ll l = 1, r = n; 18 while (l < r-2) { 19 ll lmid = (l + r) >> 1; 20 ll rmid = (lmid + r) >> 1; 21 if (judge(lmid) < judge(rmid)) 22 l = lmid; 23 else r = rmid; 24 } 25 cout << max(judge(r), judge((l + r) >> 1)) << "\n"; 26 } 27 return 0; 28 }
cf822D,遍历素因子的技巧值得学习。以及貌似第一发猜的结论好像是对的但是我写挂了……but还是正解优雅。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 const int maxn = 5e6 + 5; 6 const int mod = 1e9 + 7; 7 const ll INF = 1e18; 8 int t, l, r; 9 ll f[maxn]; 10 int primes[maxn]; 11 12 void init() { 13 for (int i = 2; i <= r; i++) { 14 primes[i] = i; 15 f[i] = INF; 16 } 17 for (int i = 2; i * i <= r; i++) {//不采集素数时不需遍历maxn 18 if (primes[i] == i) { 19 for (int j = i * i; j <= r; j += i) 20 primes[j] = min(primes[j], i); 21 } 22 } 23 for (int i = 2; i <= r; i++) { 24 for (int j = i; j != 1; j /= primes[j]) {//遍历素因子 25 f[i] = min(f[i], f[i / primes[j]] + 1LL * i * (primes[j] - 1) / 2LL); 26 } 27 } 28 } 29 30 int main() { 31 scanf("%d%d%d", &t, &l, &r); 32 init(); 33 ll ans = 0, tt = 1; 34 for (int i = l; i <= r; i++) { 35 f[i] %= mod; 36 ans = (ans + tt * f[i]) % mod; 37 tt = tt * t % mod; 38 } 39 cout << ans << endl; 40 return 0; 41 }