PloadyFree

avx2

Oct 18th, 2019
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.47 KB | None | 0 0
  1. https://codeforces.com/gym/101485/submission/62876199 Problem G
  2.  
  3. #ifndef ONLINE_JUDGE
  4. #pragma GCC optimize("O0")
  5. #pragma GCC target("sse4.2")
  6. #elif ONLINE_JUDGE
  7. #pragma GCC optimize("Ofast")
  8. #pragma GCC target("avx2")
  9. #endif
  10.  
  11. #include <bits/stdc++.h>
  12. #include <x86intrin.h>
  13.  
  14. using namespace std;
  15.  
  16. #define ALIGN 32
  17. const int maxn = 200000;
  18. alignas(ALIGN) int a[maxn];
  19. alignas(ALIGN) int b[maxn];
  20. alignas(ALIGN) int c[maxn];
  21. alignas(ALIGN) int posb[maxn];
  22. alignas(ALIGN) int posc[maxn];
  23. alignas(ALIGN) int specialC[maxn];
  24.  
  25. #define PACK_SIZE 8
  26.  
  27. int find1(int pb, int pc, int x) {
  28.   int result = 0;
  29.   for (int i = 0; i + PACK_SIZE <= pb; i += PACK_SIZE) {
  30.     for (int j = 0; j < PACK_SIZE; j++) {
  31.       result += b[i + j] < x && specialC[i + j] < pc;
  32.     }
  33.   }
  34.   for (int i = pb / PACK_SIZE * PACK_SIZE; i < pb; i++) result += b[i] < x && specialC[i] < pc;
  35.   return result;
  36. }
  37.  
  38. int find2(int pb, int pc, int x) {
  39.   __m256i accum = _mm256_setzero_si256();
  40.   __m256i xs = _mm256_set1_epi32(x);
  41.   __m256i pcs = _mm256_set1_epi32(pc);
  42.   __m256i ones = _mm256_set1_epi32(1);
  43.   for (int i = 0; i + PACK_SIZE <= pb; i += PACK_SIZE) {
  44.     __m256i bs = _mm256_load_si256((__m256i *) &b[i]);
  45.     __m256i cs = _mm256_load_si256((__m256i *) &specialC[i]);
  46.     __m256i cmp1 = _mm256_cmpgt_epi32(pcs, cs);
  47.     __m256i cmp2 = _mm256_cmpgt_epi32(xs, bs);
  48.     __m256i res = _mm256_and_si256(cmp1, cmp2);
  49.     __m256i res1 = _mm256_and_si256(res, ones);
  50.     accum = _mm256_add_epi32(accum, res1);
  51.   }
  52.   int result = 0;
  53.   int* array = (int*) &accum;
  54.   for (int i = 0; i < PACK_SIZE; i++) result += array[i];
  55.   for (int i = pb / PACK_SIZE * PACK_SIZE; i < pb; i++) result += b[i] < x && specialC[i] < pc;
  56.   return result;
  57. }
  58.  
  59. int main(int argc, char *argv[]) {
  60.   ios::sync_with_stdio(false);
  61.   cin.tie(nullptr);
  62.  
  63.   int n;
  64.   cin >> n;
  65.   for (int i = 0; i < n; i++) cin >> a[i], a[i]--;
  66.   for (int i = 0; i < n; i++) cin >> b[i], b[i]--;
  67.   for (int i = 0; i < n; i++) cin >> c[i], c[i]--;
  68.   for (int i = 0; i < n; i++) posb[b[i]] = i;
  69.   for (int i = 0; i < n; i++) posc[c[i]] = i;
  70.   for (int i = 0; i < n; i++) b[posb[a[i]]] = i;
  71.   for (int i = 0; i < n; i++) c[posc[a[i]]] = i;
  72.   for (int i = 0; i < n; i++) posb[b[i]] = i;
  73.   for (int i = 0; i < n; i++) posc[c[i]] = i;
  74.   for (int i = 0; i < n; i++) specialC[i] = posc[b[i]];
  75.   long long answer = 0;
  76.   for (int i = 0; i < n; i++) {
  77.     int pb = posb[i];
  78.     int pc = posc[i];
  79.     answer += find2(pb,pc,i);
  80.   }
  81.   cout << answer;
  82. }
Advertisement
Add Comment
Please, Sign In to add comment