1 solutions
-
0
代码如下,基本上就是把题目操作暴力地用 avx 相关库实现,注意区间操作上会存在散块,就像提示中说的一样。
可以简单在这里简单学习一下有关 SIMD 的使用。
虽然这东西在一般的算法竞赛当中都不让用,但是遇到一些掺入了系统相关的比赛,或许会有用武之地。
#include <stdio.h> #include <algorithm> #include <immintrin.h> #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,avx512f,avx512vl,popcnt,tune=native") typedef long long i64; i64 rd() { i64 k = 0, f = 1; char s = getchar(); while (s < '0' || s > '9') f = (s == '-') ? 0 : f, s = getchar(); while (s >= '0' && s <= '9') k = (k << 1) + (k << 3) + (s ^ '0'), s = getchar(); return f ? k : -k; } void wr(i64 x) { if (x < 0) putchar('-'), x = -x; if (x > 9) wr(x / 10); putchar((x % 10) ^ '0'); } const int N = 100010, B = 2, mask = (1 << B) - 1; const i64 INF = (i64)1 << 63; int n, q, blk; // 0-index interval : [l, r) i64 *a; int op, l, r; __m256i A[N >> B]; i64 *res; __m256i ans; // add (i-l+1)t to a[i] for (i\in [l, r]) inline void modify(int l, int r, i64 t) { i64 l_off = t, r_off = (r - l) * t; while ((l & mask) && (l < r)) a[l++] += l_off, l_off += t; if (l == r) return; while ((r & mask) && (l < r)) a[--r] += r_off, r_off -= t; if (l == r) return; // notice set_epi64x : 3,2,1,0 __m256i add = _mm256_set_epi64x(l_off + (t << 1) + t, l_off + (t << 1), l_off + t, l_off); __m256i off = _mm256_set1_epi64x(t << 2); for (l >>= B, r >>= B; l < r; ++l) A[l] = _mm256_add_epi64(A[l], add), add = _mm256_add_epi64(add, off); } inline void _swap(int x, int y) { i64 tmp = a[x]; a[x] = a[y], a[y] = tmp; } // query max a[i] for (i\in [l, r]) i64 query(int l, int r) { i64 ret = INF; while ((l & mask) && (l < r)) ret = std::max(ret, a[l++]); if (l == r) return ret; while ((r & mask) && (l < r)) ret = std::max(ret, a[--r]); if (l == r) return ret; ans = _mm256_set1_epi64x(INF); for (l >>= B, r >>= B; l < r; ++l) ans = _mm256_max_epi64(ans, A[l]); for (int i = 0; i <= mask; ++i) ret = std::max(ret, res[i]); return ret; } int main() { n = rd(), q = rd(), a = (i64 *)(&A), res = (i64 *)(&ans), blk = (n + mask) >> B; for (int i = 0; i < n; ++i) a[i] = rd(); while (q--) { op = rd(), l = rd(), r = rd(); switch (op) { case 3: modify(l - 1, r, rd()); break; case 2: _swap(l - 1, r - 1); break; case 1: wr(std::max(query(l - 1, r) - a[0], 0ll)), putchar('\n'); break; } // for (int i = 0; i < n; ++i, putchar(i == n ? '\n' : ' ')) wr(query(i, i + 1)); } }
Information
- ID
- 180
- Time
- 1500ms
- Memory
- 128MiB
- Difficulty
- 7
- Tags
- # Submissions
- 13
- Accepted
- 1
- Uploaded By