(打表找规律+前缀异或和)MORE XOR

待我称王封你为后i 2022-02-16 14:02 311阅读 0赞

题目链接:https://nanti.jisuanke.com/t/38230

比赛的时候也在推规律,可惜手动推错了~再者推出来还要用前缀异或和来解决,不然时间复杂度太高,会TLE.

之前不知道用前缀异或和,首先做个小题目:(前缀异或和)51nod 2128 前缀异或

  1. //队友写的打表代码
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. const int maxn=1e5+10;
  5. int s[maxn],p[maxn]={0};
  6. int f(int l,int r)
  7. {
  8. int x=0;
  9. for(;l<=r;l++){
  10. x^=s[l];
  11. p[s[l]]++;
  12. }
  13. return x;
  14. }
  15. int g(int l,int r)
  16. {
  17. int x=0;
  18. for(int i=l;i<=r;i++)
  19. for(int j=i;j<=r;j++)
  20. x^=f(i,j);
  21. return x;
  22. }
  23. int w(int l,int r)
  24. {
  25. int x=0;
  26. for(int i=l;i<=r;i++)
  27. for(int j=i;j<=r;j++)
  28. x^=g(i,j);
  29. return x;
  30. }
  31. int main()
  32. {
  33. freopen("in.txt","r",stdin);
  34. int t;
  35. scanf("%d",&t);
  36. while(t--){
  37. int n,q;
  38. scanf("%d",&n);
  39. for(int i=1;i<=n;i++)
  40. scanf("%d",&s[i]);
  41. scanf("%d",&q);
  42. while(q--){
  43. int l,r;
  44. memset(p,0,sizeof(p));
  45. scanf("%d %d",&l,&r);
  46. //printf("%d\n",w(l,r));
  47. w(l,r);
  48. printf("q=%d ",20-q);
  49. for(int i=1;i<=n;i++)
  50. if(p[i])
  51. printf("%d:%d ",i,p[i]%2);
  52. printf("\n");
  53. }
  54. }
  55. return 0;
  56. }
  57. /*
  58. 输入数据:
  59. 1
  60. 20
  61. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  62. 20
  63. 1 1
  64. 1 2
  65. 1 3
  66. 1 4
  67. 1 5
  68. 1 6
  69. 1 7
  70. 1 8
  71. 1 9
  72. 1 10
  73. 1 11
  74. 1 12
  75. 1 13
  76. 1 14
  77. 1 15
  78. 1 16
  79. 1 17
  80. 1 18
  81. 1 19
  82. 1 20
  83. */

打表可以看出是以4为周期的,0表示这个数不参与异或,1表示这个数要参与异或。

mod4余1:1000

mod4余2:1100

mod4余3:0100

mod4余0:0000

题目AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=1e5+10;
  4. int a[maxn];
  5. int main(){
  6. int t;
  7. scanf("%d",&t);
  8. while(t--){
  9. int n,q,l,r;
  10. scanf("%d",&n);
  11. for(int i=1;i<=n;i++){
  12. scanf("%d",&a[i]);
  13. }
  14. for(int i=5;i<=n;i++){
  15. a[i]^=a[i-4]; //因为答案是4为周期的,所以我们将mod4余数相等的相异或
  16. }
  17. scanf("%d",&q);
  18. while(q--){
  19. scanf("%d%d",&l,&r);
  20. int res=0;
  21. if((r-l+1)%4==1){
  22. res^=a[r];
  23. if(l>4) res^=a[l-4]; //1000
  24. }else if((r-l+1)%4==2){
  25. res^=a[r]^a[r-1];
  26. if(l>=3) res^=a[l-3]; //1100
  27. if(l>=4) res^=a[l-4];
  28. }else if((r-l+1)%4==3){ //0100
  29. res^=a[r-1];
  30. if(l>=3) res^=a[l-3];
  31. }
  32. printf("%d\n",res);
  33. }
  34. }
  35. return 0;
  36. }

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读