题目链接

我觉得AVX2指令集不够爽,于是写了AVX512.到官网查了一天手册,直接拿下最优解

Solution [Ynoi2018]五彩斑斓的世界

题目大意:给定一个长度为\(n\)的序列.每次将\([l,r]\)内大于\(x\)的数减\(x\).询问\([l,r]\)内\(x\)出现了多少次

分析:还能有啥分析,直接暴力,指令集优化一下就可以了

所有函数都可以在Intel手册查到

首先,既然我们要用指令集,得\(CPU\)资瓷才行

#include <stdint.h>
#include <iostream>
#include <cpuid.h>
static void cpuid(uint32_t func, uint32_t sub, uint32_t data[4]) {__cpuid_count(func, sub, data[0], data[1], data[2], data[3]);
}
int main() {uint32_t data[4];char str[48];for(int i = 0; i < 3; ++i) {cpuid(0x80000002 + i, 0, data);for(int j = 0; j < 4; ++j)reinterpret_cast<uint32_t*>(str)[i * 4 + j] = data[j];}std::cout << str;
}

将如上代码丢入在线\(IDE\),得到评测姬\(CPU\)型号

注意:\(Luogu\)采用集群评测,每次得到的\(CPU\)型号不一定相同.(也就是过不了多交几次的原理?)
在我这儿,得到的型号为:

Intel(R) Xeon(R) Gold 6149 CPU @ 3.10GHz

在\(Intel\)官网是查不到这颗\(CPU\)的信息的,考虑到\(Luogu\)基于阿里云,那这颗\(CPU\)就多半是阿里云定制的.我们可以查询与它规格相近的Xeon(R) Gold 6148
在Intel官网查到这颗\(CPU\)支持的指令集:

SSE4.2, AVX, AVX2, AVX-512

你谷非常良心啊,其它\(OJ\)用的都是酷睿,你谷上了至强可扩展……

  • CodeForces: i3-8100
  • LibreOJ: i5-3470
  • bzoj: 想必这OJ的CPU一定古(垃)老(圾),就不查了(而且也查不到)

所以注意了请不要在考场上使用AVX512指令集,用AVX256都是冒险

CCF所采用的i7-8700k仅支持到AVX2,AVX512要等到Cannon Lake去了

关于AMD:她死了

先上代码,然后下文再讲解函数用法:

#pragma GCC target("avx,avx2,avx512f")
#include <immintrin.h>#include <cstdio>
using namespace std;
const int maxn = 1e5 + 100;
int n,m,val[maxn],*arr;
inline void modify(int *left,int *right,int x){__m512i subval = _mm512_set_epi32(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x);while(((long long)(left) % 64) && left <= right){//64位对齐if(*left > x)*left -= x;left++;}while(left + 15 <= right){__m512i tmp = _mm512_load_epi32(left);_mm512_store_epi32(left,_mm512_mask_sub_epi32(tmp,_mm512_cmpgt_epi32_mask(tmp,subval),tmp,subval));//如果tmp对应位大于subval对应位就是两数相减的值,否则不变left += 16;}while(left <= right){if(*left > x)*left -= x;left++;}
}
inline int query(int *left,int *right,int x){int ret = 0;__m512i sum = _mm512_setzero_epi32(),one = _mm512_set_epi32(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);while(((long long)(left) % 64) && left <= right){//64位对齐if(*left == x)ret++;left++;}__m512i tocmp = _mm512_set_epi32(x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x);while(left + 15 <= right){__m512i tmp = _mm512_load_epi32(left);sum = _mm512_mask_add_epi32(sum,_mm512_cmpeq_epi32_mask(tmp,tocmp),sum,one);//如果tmp和tocmp对应位相等,sum对应位+1否则不变left += 16;}while (left <= right){if (*left == x) ret++;left++;}_mm512_store_epi32(arr,sum);for(int i = 0;i < 16;i++)ret += arr[i];return ret;
}
int main()
{scanf("%d %d",&n,&m);arr = new int[128];while((long long)(arr) % 64)arr++;//64位对齐for(int i = 1;i <= n;i++)val[i] = read();for(int i = 1;i <= m;i++){int opt,l,r,x;scanf("%d %d %d %d",&opt,&l,&r,&x);if(opt == 1)modify(val + l,val + r,x);else printf("%d\n",query(val + l,val + r,x));}return 0;
}

从指令集名字我们可以看出来,$AVX512指令集一次性可以处理\(512\)位数据,也就是\(16\)位\(int\)

AVX512指令集的基本数据类型:

__m512,__m512d,__m512i
分别存储单精度浮点数,双精度浮点数,整数

这次我们用__m512i,所以另外两个我们不讲,它可以存储\(64\)个\(char\),\(32\)个\(short\),\(16\)个\(int\),\(8\)个\(long\;long\)

__m512i _mm512_set_epi32 (int e15, int e14, int e13, int e12, int e11, int e10, int e9, int e8, int e7, int e6, int e5, int e4, int e3, int e2, int e1, int e0)

这个函数把\(16\)个\(int\)打包,\(epi32\)显然指的是每个元素的大小(位数),\(epi64\)就适用于\(long\;long\)

__m512i _mm512_load_epi32 (void const* mem_addr)

这个函数从指定内存地址读取\(512\)位,注意mem_addr一定要64位对齐,否则会抛出一般保护性异常

void _mm512_store_epi32 (void* mem_addr, __m512i a)

这个函数将\(a\)中的值存储到\(mem\_addr\)开始的地址中,同样要\(64\)位对齐

__mmask16 _mm512_cmpgt_epi32_mask (__m512i a, __m512i b)

这个函数比较\(a\)和\(b\),返回一个掩码.如果\(a\)对应位$ >$ \(b\)对应位 掩码对应位为\(1\)

__m512i _mm512_mask_add_epi32 (__m512i src, __mmask16 k, __m512i a, __m512i b)

如果写掩码\(k\)对应位为\(0\),那么返回值对应位就是\(src\)的对应位,否则就是\(a\)的对应位加\(b\)的对应位

__m512i _mm512_mask_sub_epi32 (__m512i src, __mmask16 k, __m512i a, __m512i b)

如果写掩码\(k\)对应位为\(0\),那么返回值对应位就是\(src\)的对应位,否则就是\(a\)的对应位减\(b\)的对应位

__mmask16 _mm512_cmpeq_epi32_mask (__m512i a, __m512i b)

这个函数返回一个掩码,如果\(a\)对应位\(=\) \(b\)对应位,掩码对应位为\(1\)

然后记得

#pragma GCC target("avx,avx2,avx512f")
#include <immintrin.h>

没了,基本上就是一个模拟.复杂度\(O(nm/16)\)

跑的挺快的,加个\(mmap\)读入优化轻松冲进2162ms

吸了氧气会变慢就比较迷了,氧气中毒?

转载于:https://www.cnblogs.com/colazcy/p/11515031.html

题解 P4117 【[Ynoi2018]五彩斑斓的世界】相关推荐

  1. P4117 [Ynoi2018] 五彩斑斓的世界

    P4117 [Ynoi2018] 五彩斑斓的世界 给你一个长为 nnn 的序列 aaa,有 mmm 次操作: 把区间 [l,r][l,r][l,r] 中大于 xxx 的数减去 xxx. 查询区间 [l ...

  2. P4117 [Ynoi2018] 五彩斑斓的世界 题解

    这题目很难,我花了三周,但题目中的图片是真的那个什么的:[Ynoi2018] 五彩斑斓的世界 - 洛谷 结尾有题目中的图片 我们先搞清楚一个前置问题:把区间 [l,r][l,r] 中所有的 xx 变成 ...

  3. luogu P4117 [Ynoi2018] 五彩斑斓的世界

    https://www.luogu.com.cn/problem/P4117 因为题目的值域只有10510^5105,并且只有减法一种操作,所以我们可以考虑均摊 把所有的减法改成加法 首先还是要分块, ...

  4. CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界(并查集+第二分块)

    CF896E Welcome home,Chtholly/[Ynoi2018]五彩斑斓的世界 description solution code description 五彩斑斓的世界 CF896E ...

  5. [Ynoi2018]五彩斑斓的世界

    五彩斑斓的世界 题解 这道题相当于是Welcome home, Chtholly的数据加强版 ,对,就是那个臭名昭著的瑟尼欧里斯树的那场比赛的最后一道题. 于是lxllxllxl亲切地将这道题命名为第 ...

  6. bzoj 5143 [Ynoi2018]五彩斑斓的世界

           二阶堂真红给了你一个长为n的序列a,有m次操作        1.把区间[l,r]中大于x的数减去x        2.查询区间[l,r]中x的出现次数        题解:       ...

  7. NOIP前的刷题记录

    因为这几天要加油,懒得每篇都来写题解了,就这里记录一下加上一句话题解好了 P4071 [SDOI2016]排列计数   组合数+错排 loj 6217 扑克牌 暴力背包 P2511 [HAOI2008 ...

  8. 2018十二月刷题列表

    Preface \(2018\)年的尾巴,不禁感慨自己这一年的蜕变只能用蜕变来形容了. 而且老叶说我们今年没的参加清北冬令营可以参加CCF在广州二中举办的冬令营,只要联赛\(390+\)就应该可以报. ...

  9. Educational Codeforces Round 119 (Rated for Div. 2) EFG 题解

    Solution 赛时切了 ABCDEG,不会 F. E 考虑使用若干个集合 S i S_i Si​ 维护各个数出现的位置,那么两个操作分别可以被抽象为: 在一个集合中加入一个数. 将集合 S x S ...

最新文章

  1. Python基本语法_基本数据类型_字典类型详解
  2. python免费入门手册-Python 基础入门教程
  3. [摘录]高效人士七习惯—从依赖到独立
  4. Gibbs sampling [Gibbs采样]
  5. java 数组遍历_Java中遍历数组使用foreach循环还是for循环?
  6. Jsoup(二)-- Jsoup查找DOM元素
  7. sklearn 常用api(一)
  8. html鼠标自动向下滑动,win10电脑中鼠标自动向下或向上滚动怎么解决
  9. RDP Wrapper 大于10.0.19041
  10. knockoutjs介绍
  11. 小程序引入vant组件
  12. 位置不可用——文件或目录损坏且无法读取
  13. 木瓜移动每日出海快讯0428:谷歌发布Q1财报
  14. java pdf 富文本_Java生成pdf,兼富文本
  15. Android WiFi热点
  16. 对今日头条问答部分的预测-未来可能会挂掉
  17. MySQL主从1205报错【转】
  18. 相对免赔额和绝对免赔额是什么意思,有什么区别?
  19. 正大国际期货:做期货交易,怎么样才能成功?
  20. js根据name获取所有的值

热门文章

  1. aes加密 java_Java中的微信支付(2):API V3 微信平台证书的获取与刷新
  2. 周涛教授:从窄门进走出宽路来!
  3. 当JAVA集合移除自身集合元素时发生的诸多问题
  4. 从腾讯的职级系统,看清自己的职场宿命(转载)
  5. java过滤器敏感字的拦截_【JavaWeb】94:如何屏蔽敏感词?
  6. XFLR5机翼分析工具下载及使用
  7. 为何韩国人日本人要努力工作原因的歪解?
  8. 串口通信数据位长度对传输数据的影响
  9. 为什么在拍摄VR全景时要用鱼眼镜头
  10. Tab切换 排斥 asyncData