A Absolute
B Counting Permutations
C Cover
D Game
#include <cstdio> using namespace std; int main() { int n; while(~scanf("%d", &n)) printf("Yes "); }
E Hack It
构造一个矩阵,使得任何子矩阵的四个角不能都为1。
#include<cstdio> using namespace std; const int n = 47; const int maxn = 3010; int mp[maxn][maxn];
int main() { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) mp[i*n+j][k*n+(j*k+i)%n]=1; printf("2000 "); for(int i=0;i<2000;i++) { for(int j=0;j<2000;j++) printf("%d", mp[i][j]); puts(""); } return 0; }
F Matrix
G Naive Operations
用线段树维护每个点被操作了多少次,然后当操作次数是b[i]的整数倍时,将sum[i]++。
新学了一种线段树的写法。
#include <iostream> #include <cstdlib> #include <cstdio> using namespace std; #define LL long long const int maxn = 100000 + 10; struct Sect { int cnt, lz; LL sum; }t[4*maxn]; int n, a[maxn], lim[maxn]; void build(int id, int l, int r) { t[id].lz = 0; t[id].sum = 0; if (l == r) { t[id].cnt = lim[l]; return; } int mid = (l+r) / 2; build(id*2, l, mid); build(id*2+1, mid+1, r); t[id].sum = t[id*2].sum + t[id*2+1].sum; t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt); } void push_down(int id) { if (t[id].lz) { t[id*2].lz += t[id].lz, t[id*2+1].lz += t[id].lz; t[id*2].cnt -= t[id].lz, t[id*2+1].cnt -= t[id].lz; t[id].lz = 0; } } void update_range(int id, int L, int R, int l, int r) { if (t[id].cnt > 1 && L <= l && r <= R) { t[id].lz++; t[id].cnt--; return; } if (t[id].cnt == 1 && l == r) { t[id].sum++; t[id].lz = 0; t[id].cnt = lim[l]; return; } int mid = (l + r) / 2; push_down(id); if (L <= mid) update_range(id*2, L, R, l, mid); if (R > mid) update_range(id*2+1, L, R, mid+1, r); t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt); t[id].sum = t[id*2].sum + t[id*2+1].sum; } LL query(int id, int L, int R, int l, int r) { if (L <= l && r <= R) return t[id].sum; int mid = (l + r) / 2; LL ans = 0; push_down(id); if (L <= mid) ans += query(id*2, L, R, l, mid); if (R > mid) ans += query(id*2+1, L, R, mid+1, r); t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt); t[id].sum = t[id*2].sum + t[id*2+1].sum; return ans; } int main() { int n, q; while(scanf("%d%d", &n, &q) != EOF) { for (int i = 1; i <= n; i++) scanf("%d", &lim[i]); build(1, 1, n); char op[maxn]; int x, y; for (int i = 1; i <= q; i++) { scanf("%s%d%d", op, &x, &y); if (op[0] == 'a') update_range(1, x, y, 1, n); else printf("%lld ", query(1, x, y, 1, n)); } } }
H Odd Shops
I Segment
J Swaps and Inversions
ans = 逆序对的数量 × min(x, y)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 100000 + 100; LL cnt = 0; int T[maxn], a[maxn]; void merge_sort(int *A, int x, int y, int *T) { if (y-x > 1) { int m = x + (y-x)/2; int p = x, q = m, i = x; merge_sort(A, x, m, T); merge_sort(A, m, y, T); while(p < m || q < y) { if (q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++]; else T[i++] = A[q++], cnt += m-p; } for (i = x; i < y; i++) A[i] = T[i]; } } int main() { int n, x, y; while(~scanf("%d%d%d", &n, &x, &y)) { for (int i = 1; i <= n; i++) scanf("%d", &a[i]); cnt = 0; merge_sort(a, 1, n+1, T); LL ans = cnt * min(x, y); printf("%lld ", ans); } }