题解:利用前缀和,求出全部区间值,而后操做排序,贪心求解便可
知识点:前缀和 + 贪心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; }