思路

由于给出的数据大小以及题意可知,这道题考察的应该是线性筛和二分查找,本人由于太弱了,没想到我居然之前接触过欧拉筛,应该也叫做线性筛吧,时间紧迫来不及多思考,比赛中用的朴素做法,估计能拿个1分2分这样,以下是我补题后的写法

参考代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1e6+3; //开到第一个大于1000000的质数
  4. const int M = 2e5+10;
  5. int n,q;
  6. vector<int> cha[M]; //查找值
  7. int a[M]; //初始数组a
  8. int pri[N],pri_num=0,lu[N],qp=0; //质数,质数个数,记录因子数组
  9. bool ji[N],zhi[M];
  10. inline void dabiao(){ //欧拉筛
  11. for(int i=2;i<=N;i++){
  12. if(!ji[i]) lu[++qp]=i;
  13. for(int j=1;lu[j]*i<=N;j++){
  14. ji[lu[j]*i]=true;
  15. if(i%lu[j]==0) break;
  16. }
  17. }
  18. for(int i=2;i<=N;i++){
  19. if(!ji[i]) pri[++pri_num]=i;
  20. }
  21. return ;
  22. }
  23. inline int find_da(int x){ //在质数表里寻找第一个大等于a[i]的数
  24. int l=1,r=pri_num;
  25. while(l<r){
  26. int mid=l+r>>1;
  27. if(pri[mid]>=x) r=mid;
  28. else l=mid+1;
  29. }
  30. return r;
  31. }
  32. inline int find_xiao(int x){ //在质数表里寻找第一个小等于a[i]的数
  33. int l=1,r=pri_num;
  34. while(l<r){
  35. int mid=l+r+1>>1;
  36. if(pri[mid]<=x) l=mid;
  37. else r=mid-1;
  38. }
  39. return l;
  40. }
  41. inline int he(int i){ //找要替换成的数
  42. int sum=0;
  43. for(auto e:cha[i]){
  44. sum+=e;
  45. }
  46. return sum;
  47. }
  48. inline void tihuan(){ //替换
  49. for(int i=1;i<=n;i++){
  50. if(cha[i].size()>0){
  51. if(!zhi[i]){ //如果不是质数要把其按照第一次的变化变为质数,如果第一次是往大取,则先变小一位质数,反之则取大一位的质数
  52. int first=cha[i][0];
  53. if(first>0){
  54. int pri_ai=find_xiao(a[i]);
  55. a[i]=pri[pri_ai];
  56. }
  57. else{
  58. int pri_ai=find_da(a[i]);
  59. a[i]=pri[pri_ai];
  60. }
  61. }
  62. int sum=he(i);
  63. if(sum>0){
  64. int pri_ai=find_xiao(a[i]);
  65. if(sum+pri_ai<pri_num){
  66. a[i]=pri[pri_ai+sum];
  67. }
  68. else a[i]=1;
  69. }
  70. else{
  71. int pri_ai=find_da(a[i]);
  72. if(sum+pri_ai>0){
  73. a[i]=pri[pri_ai+sum];
  74. }
  75. else a[i]=0;
  76. }
  77. }
  78. }
  79. return ;
  80. }
  81. int main(){
  82. scanf("%d %d",&n,&q);
  83. dabiao(); //先打一个质数表
  84. for(int i=1;i<=n;i++){
  85. scanf("%d",&a[i]);
  86. if(pri[find_da(a[i])]==a[i]){ //记录每一个数是不是质数
  87. zhi[i]=true;
  88. }
  89. }
  90. while(q--){
  91. int op,k,x;
  92. scanf("%d %d %d",&op,&k,&x);
  93. for(int i=k;i<=n;i+=k){
  94. if(op==1){
  95. cha[i].push_back(x); //记录每一次的搜索
  96. }
  97. else{
  98. cha[i].push_back(0-x);
  99. }
  100. }
  101. }
  102. tihuan(); //替换
  103. for(int i=1;i<=n;i++){
  104. printf("%d ",a[i]);
  105. }
  106. printf("\n");
  107. return 0;
  108. }
点赞(0)
 

9.9 分

2 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论