记录编号 53757 评测结果 AAAAAAAAAA
题目名称 [HAOI 2009]求回文串 最终得分 100
用户昵称 Gravatarfeng 是否通过 通过
代码语言 C++ 运行时间 4.154 s
提交时间 2013-03-05 11:10:03 内存使用 40.37 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <deque>
  4. #include <algorithm>
  5. #include <iostream>
  6. using namespace std;
  7. const int MAXN=1000005;
  8. const int oo=0x7fffffff;
  9. struct tt{
  10. int delta,data;
  11. }tree[4000001];
  12. deque<int> q[26];
  13. char st[MAXN];
  14.  
  15. int ax,ay,del;
  16. int a[MAXN];
  17. int N;
  18.  
  19. void updata(int left,int right,int root){
  20. int mid;
  21. int delta;
  22. if (ax>right||ay<left) return;
  23. if (ax<=left&&right<=ay){
  24. tree[root].data+=del;
  25. tree[root].delta+=del;
  26. return;
  27. }
  28. mid=(left+right)/2;
  29. delta=tree[root].delta;
  30. tree[root*2].delta+=delta;
  31. tree[root*2].data+=delta;
  32. tree[root*2+1].data+=delta;
  33. tree[root*2+1].delta+=delta;
  34. tree[root].delta=0;
  35. updata(left,mid,root*2);
  36. updata(mid+1,right,root*2+1);
  37. tree[root].data=tree[root*2].data+tree[root*2+1].data;
  38. }
  39. int search(int left,int right,int root){
  40. int delta;
  41. int mid,templ,tempr;
  42. if (ax>right || ay<left) return 0;
  43. if (ax<=left && right<=ay){
  44. return tree[root].data;
  45. }
  46. mid=(left+right)/2;
  47. delta=tree[root].delta;
  48. tree[root*2].delta+=delta;
  49. tree[root*2].data+=delta;
  50. tree[root*2+1].data+=delta;
  51. tree[root*2+1].delta+=delta;
  52. tree[root].delta=0;
  53. templ=search(left,mid,root*2);
  54. tempr=search(mid+1,right,root*2+1);
  55. return templ+tempr;
  56. }
  57. bool used[MAXN];
  58. int str[MAXN];
  59. int main()
  60. {
  61. freopen("string!.in","r",stdin);
  62. freopen("string!.out","w",stdout);
  63. scanf("%s",st+1);
  64. int l=1,r=strlen(st+1);
  65. N=r;
  66. for(int i=l;i<=r;i++)
  67. q[str[i]=st[i]-'A'].push_back(i);
  68. bool flag=false;
  69. for(int i=0;i<26;i++)
  70. if (q[i].size()&1)
  71. {
  72. if (!flag) flag=true;
  73. else
  74. {
  75. printf("-1\n");
  76. return 0;
  77. }
  78. }
  79. long long re=0;
  80. while(l<r)
  81. {
  82. while(used[l])
  83. l++;
  84. while(used[r])
  85. r--;
  86. if (l>=r)
  87. break;
  88. if (str[l]==str[r])
  89. {
  90. q[str[l]].pop_front();
  91. q[str[l]].pop_back();
  92. l++,r--;
  93. }
  94. else
  95. {
  96. int w1,w2;
  97. if (q[str[l]].size()>=2)
  98. {
  99. int t=q[str[l]].back();
  100. ax=t;
  101. ay=r;
  102. int tmp=search(1,N,1);
  103. w1=r-t-tmp;
  104. }
  105. else w1=oo;
  106. if (q[str[r]].size()>=2)
  107. {
  108. int t=q[str[r]].front();
  109. ax=l;
  110. ay=t;
  111. int tmp=search(1,N,1);
  112. w2=t-l-tmp;
  113. }
  114. else w2=oo;
  115. if (w1<w2)
  116. {
  117. re+=w1;
  118. int t=q[str[l]].back();
  119. ax=t;
  120. ay=t;
  121. del=1;
  122. updata(1,N,1);
  123. used[t]=true;
  124. q[str[l]].pop_back();
  125. q[str[l]].pop_front();
  126. l++;
  127. }
  128. else
  129. {
  130. re+=w2;
  131. int t=q[str[r]].front();
  132. ax=t;
  133. ay=t;
  134. del=1;
  135. updata(1,N,1);
  136. used[t]=true;
  137. q[str[r]].pop_back();
  138. q[str[r]].pop_front();
  139. r--;
  140. }
  141. }
  142. }
  143. cout<<re<<endl;
  144. //printf("%lld\n",re);
  145. return 0;
  146. }