題解:利用前綴和,求出全部區間值,而後操做排序,貪心求解便可
知識點:前綴和 + 貪心ios
AC代碼:web
#include<iostream> #include<stdio.h> #include<algorithm> #include<queue> #include<map> #include<string.h> #include<string> using namespace std; const int N = 1e6 + 15; #define ll long long #define inf 0x3f3f3f3f ll a[N], sum[N]; ll b[N]; int main() { int t; cin >> t; while (t--) { int n, m; cin >> n >> m; for (int i = 0; i < n; i++) cin >> a[i]; sum[0] = a[0]; for (int i = 1; i < n; i++) sum[i] = sum[i - 1] + a[i]; int k = 0; for (int i = 0; i < m; i++) { int l, r; cin >> l >> r; int x = sum[r - 1] - sum[l - 2]; b[k++] = x; } sort(b, b + k); ll res = 0; for (int i = 1; i <= k; i++) res += i * b[i - 1]; cout << res << endl; } return 0; }
題解:map瞎搞,記錄前綴的數量,暴力就能夠過,對於我這種只會作簽到題的菜雞。不過這題更好的解法是字典樹。
注意:記得把全部的有關數據都開ll,以避免相乘的時候出現精度丟失svg
#include<iostream> #include<stdio.h> #include<algorithm> #include<queue> #include<map> #include<string.h> #include<string> using namespace std; const int N = 5e5 + 15; #define ll long long #define inf 0x3f3f3f3f ll val[N]; string str[N]; map<string, ll>mp; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int n, m; cin >> n >> m; ll s_val[30]; for (int i = 0; i < 26; i++) cin >> s_val[i]; for (int i = 0; i < n; i++) { cin >> str[i]; int str_len = str[i].length(); string s; val[i] = 1; for (int j = 0; j < str_len; j++) { s += str[i][j]; mp[s] += 1; val[i] = (val[i] * s_val[str[i][j] - 'a']) % m; } } for (int i = 0; i < n; i++) { string s; int v = 1; int ans = 0; for (int j = 0; j < str[i].length(); j++) { v = (v * s_val[str[i][j] - 'a']) % m; s += str[i][j]; if (v > val[i]) ans += mp[s]; } cout << ans << " "; } cout << endl; return 0; }
題解:線段樹的更新,改點,異或的應用ui
AC代碼:spa
#include<iostream> #include<stdio.h> #include<algorithm> #include<queue> #include<map> #include<string.h> #include<string> using namespace std; const int N = 2e5 + 15; #define ll long long #define inf 0x3f3f3f3f struct Tree { int l, r; int val,sum; }tree[N * 2]; int a[N]; void pushup(int cur) { if ((tree[cur * 2 + 1].l - tree[cur].l) % 2 == 0) tree[cur].val = tree[cur * 2].val ^ tree[cur * 2 + 1].val; else tree[cur].val = tree[cur * 2].val ^ (tree[cur * 2 + 1].sum ^ tree[cur * 2 + 1].val); tree[cur].sum = tree[cur * 2].sum ^ tree[cur * 2 + 1].sum; } void build(int l, int r, int step) { int mid = (l + r) / 2; tree[step].l = l, tree[step].r = r; if (l == r) { tree[step].val = a[l]; tree[step].sum = a[l]; return; } build(l, mid, step * 2); build(mid + 1, r, step * 2 + 1); pushup(step); } void query(int l, int r, int &x, int &y, int step) { if (tree[step].l == l && tree[step].r == r) { x = tree[step].val, y = tree[step].sum; return; } int mid = (tree[step].l + tree[step].r) / 2; if (r <= mid) query(l, r, x, y, step * 2); else if (l > mid) query(l, r, x, y, step * 2 + 1); else { int a, b, c, d; query(l, mid, a, b, step * 2); query(mid + 1, r, c, d, step * 2 + 1); if ((tree[step * 2 + 1].l - l) % 2 == 0) { x = a ^ c; y = b ^ d; } else { x = a ^ (d ^ c); y = b ^ d; } } } void update(int tar, int val, int step) { int l = tree[step].l, r = tree[step].r; if (l == r) { tree[step].val = val; tree[step].sum = val; return; } int mid = (l + r) / 2; if (tar <= mid) update(tar, val, step * 2); else update(tar, val, step * 2 + 1); pushup(step); } int main() { int t; scanf("%d", &t); int k = 1; while (t--) { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); build(1, n, 1); printf("Case #%d:\n", k++); for (int i = 0; i < m; i++) { int op, x, y; scanf("%d%d%d", &op, &x, &y); if (op == 0) update(x, y, 1); else { if ((y - x + 1) % 2 != 0) { int a, b; query(x, y, a, b, 1); printf("%d\n", a); } else printf("0\n"); } } } return 0; }