记录编号 224078 评测结果 AAAAAAAAAA
题目名称 [HNOI 2004] 邮递员 最终得分 100
用户昵称 Gravatar/k 是否通过 通过
代码语言 C++ 运行时间 0.045 s
提交时间 2016-02-15 14:32:41 内存使用 0.72 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define W(i) ((i-1)<<1)
  5. using namespace std;
  6. struct udata
  7. {
  8. int x[15];
  9. friend udata operator + (udata aa,udata bb)
  10. {
  11. int *A=aa.x,*B=bb.x;
  12. int h=0;
  13. if(A[0]<B[0])
  14. A[0]=B[0];
  15. for(int i=1;i<=A[0];i++)
  16. {
  17. A[i]=A[i]+B[i];
  18. A[i]=A[i]+h;
  19. h=A[i]/100000000;
  20. A[i]%=100000000;
  21. }
  22. if(h)
  23. A[++A[0]]=h;
  24. return aa;
  25. }
  26. }qz[2][3020],zhi,ans;
  27. long long q[2][3020];
  28. int hash[3020];
  29. int tp[2],now=1,n,m;
  30. inline void ghashin(long long s)//s状态
  31. {
  32. int p=s%3020;
  33. int o=p-1;
  34. while(hash[p]!=0)
  35. {
  36. if(s==q[now^1][hash[p]])
  37. {
  38. qz[now^1][hash[p]]=qz[now^1][hash[p]]+zhi;
  39. return;
  40. }
  41. p++;
  42. if(p==3020)
  43. p=0;
  44. }
  45. ++tp[now^1];
  46. hash[p]=tp[now^1];
  47. qz[now^1][tp[now^1]]=zhi;
  48. q[now^1][tp[now^1]]=s;
  49. }
  50. int main()
  51. {
  52. freopen("postman.in","r",stdin);
  53. freopen("postman.out","w",stdout);
  54. scanf("%d%d",&m,&n);
  55. if(m==1||n==1)
  56. {
  57. printf("1");
  58. return 0;
  59. }
  60. qz[0][1].x[0]=qz[0][1].x[1]=1;
  61. tp[0]=1;
  62. for(int i=1;i<=n;i++)
  63. {
  64. for(int j=1;j<=m;j++)
  65. {
  66. now^=1;
  67. memset(hash,0,sizeof(hash));
  68. tp[now^1]=0;
  69. for(int s=1;s<=tp[now];++s)
  70. {
  71. zhi=qz[now][s];
  72. long long ztai=q[now][s];
  73. int p=(ztai>>W(j))&3,qq=(ztai>>W(j+1))&3;
  74. if(p==0&&qq==0)
  75. {
  76. if(i==n||j==m)
  77. continue;
  78. ztai^=(1<<W(j));
  79. ztai^=(1<<W(j+1))*2;
  80. ghashin(ztai);
  81. }
  82. else if(p==1&&qq==1)
  83. {
  84. int d=1;
  85. for(int y=j+2;y<=m+1;y++)
  86. {
  87. int o=(ztai>>W(y))&3;
  88. if(o==1)
  89. ++d;
  90. if(o==2)
  91. --d;
  92. if(d==0)
  93. {
  94. ztai^=(1<<W(y))*2;//清除原有右括号标记
  95. ztai^=(1<<W(y));//添加左括号标记
  96. break;
  97. }
  98. }
  99. ztai^=1<<W(j);
  100. ztai^=1<<W(j+1);
  101. ghashin(ztai);
  102. }
  103. else if(p==2&&qq==2)
  104. {
  105. int d=-1;
  106. for(int y=j-1;y>=0;y--)
  107. {
  108. int o=(ztai>>W(y))&3;
  109. if(o==1)
  110. ++d;
  111. if(o==2)
  112. --d;
  113. if(d==0)
  114. {
  115. ztai^=(1<<W(y));
  116. ztai^=(1<<W(y))*2;
  117. break;
  118. }
  119. }
  120. ztai^=(1<<W(j))*2;
  121. ztai^=(1<<W(j+1))*2;
  122. ghashin(ztai);
  123. }
  124. else if(p==1&&qq==2)
  125. {
  126. if(i==n&&j==m)
  127. {
  128. //printf("%d %d\n",i,j);
  129. ans=ans+zhi;
  130. }
  131. }
  132. else if(p==2&&qq==1)
  133. {
  134. ztai^=(1<<W(j))*2;
  135. ztai^=(1<<W(j+1));
  136. ghashin(ztai);
  137. }
  138. else if(p>0&&qq==0)
  139. {
  140. if(i!=n)
  141. ghashin(ztai);
  142. if(j==m)
  143. continue;
  144. //printf("A%lld",ztai);
  145. ztai^=(1<<W(j))*p;
  146. ztai^=(1<<W(j+1))*p;
  147. ghashin(ztai);
  148. //printf("B");
  149. }
  150. else
  151. {
  152. if(j!=m)
  153. ghashin(ztai);
  154. if(i==n)
  155. continue;
  156. ztai^=(1<<W(j))*qq;
  157. ztai^=(1<<W(j+1))*qq;
  158. ghashin(ztai);
  159. }
  160. }
  161. }
  162. for(int y=1;y<=tp[now^1];y++)
  163. q[now^1][y]=(q[now^1][y]<<2);
  164. }
  165. ans=ans+ans;
  166. printf("%d",ans.x[ans.x[0]]);
  167. for(int i=ans.x[0]-1;i>0;i--)
  168. printf("%08d",ans.x[i]);
  169. getchar();
  170. getchar();
  171. }