寻找三元组(i,j,k),使得(i,j)(j,k)都是回文字串,其中i<=j<k.

可以发现,对于每一位i,只要预处理出来有多少个以i为右端的回文串和以i为左端的回文串。把那些串的另一端的坐标和计算出来就可以了。

然后ans = ∑cntR[i]*cntL[i+1]

这里cntR[i]记录以i为右端的回文串的左端坐标和。cntL[i]同理。

然后这道题的数据范围是1e6,多case。必须要O(n)才能过。

首先用O(n)的Manacher处理每一位的回文半径,之后遍历处理

可以发现这里需要O(n)复杂度给指定区间加上一个等差序列。于是开几个数组维护,空间换时间。

用cnt_add记录加了多少次,add记录首项加了多少,这样从首项往后递推,每次add[i+1] = add[i]-cnt_add[i] cnt_add[i+1] += cnt_add[i] cntL[i] += add[i]

这样可以从首项更新到字符串尾。但是我们要更新一段值,就有一段多加了,于是就再开一个mns记录多加的的值.

比如要更新[l,r] 那么就给mns[r+1]置为add[r+1]时的值。这样就可以把多加的抵消了。同时也要维护一个cnt_mns记录次数。

最后还要注意分回文长度奇偶讨论。

//坑了好久的题。最开始想到了用树状数组维护cnt,成段更新,然而卡log。

  1 #include <cstdio>
  2 #include <ctype.h>
  3 #include <cstring>
  4 #include <algorithm>
  5
  6 #define LL long long
  7 #define lson rt<<1,l,mid
  8 #define rson rt<<1|1,mid+1,r
  9 #define root 1,N,1
 10 using namespace std;
 11
 12 const int maxn = 1e6+100;
 13 const LL MOD = 1e9+7;
 14
 15 char Ma[2*maxn];
 16 int Mp[2*maxn];
 17 void update(LL &x,LL d)
 18 {
 19     x += d;
 20     if(x >= MOD) x -= MOD;
 21     if(x < 0) x += MOD;
 22 }
 23
 24 void Manacher(char s[],int len)
 25 {
 26     memset(Mp,0,sizeof Mp);
 27     int l = 0;
 28     Ma[l++] = '$';
 29     Ma[l++] = '#';
 30     for(int i=0;i<len;i++)
 31     {
 32         Ma[l++] = s[i];
 33         Ma[l++] = '#';
 34     }
 35     Ma[l] = 0;
 36     int mx = 0,id = 0;
 37     for(int i=0;i<l;i++)
 38     {
 39         Mp[i] = mx > i ? min(Mp[2*id-i],mx-i) : 1;
 40         while(Ma[i+Mp[i]] == Ma[i-Mp[i]] ) Mp[i]++;
 41         if(i + Mp[i] > mx)
 42         {
 43             mx = i+Mp[i];
 44             id = i;
 45         }
 46     }
 47 }
 48
 49 char line[maxn];
 50 int p[maxn];
 51 LL cntL[maxn],cntR[maxn];
 52 LL add[maxn],mns[maxn];
 53 LL cnt_add[maxn],cnt_mns[maxn];
 54
 55 void init()
 56 {
 57     memset(cnt_mns,0,sizeof cnt_mns);
 58     memset(cnt_add,0,sizeof cnt_add);
 59     memset(add,0,sizeof add);
 60     memset(mns,0,sizeof mns);
 61 }
 62
 63 LL ans = 0;
 64 void solve(int len)
 65 {
 66     init();
 67     for(int i=2;i<2*len+1;i++)
 68     {
 69         int tmp = Mp[i];
 70         if(Ma[i] == '#')
 71         {
 72             int cur = i/2+1,L = (i-tmp)/2+1, R = (i+tmp)/2-1,r = (tmp-1)/2;
 73             update(add[L],R);
 74             update(mns[cur],R-r);
 75             cnt_add[L] ++;
 76             cnt_mns[cur]++;
 77         }else
 78         {
 79             int cur = i/2,L = (i-tmp)/2+1, R = (i+tmp)/2-1,r = 1+(tmp-1)/2;
 80             update(add[L],R);
 81             update(mns[cur+1],R-r);
 82             cnt_add[L] ++;
 83             cnt_mns[cur+1]++;
 84         }
 85     }
 86     for(int i=1;i<=len;i++)
 87     {
 88         update(cntL[i],add[i]-mns[i]);
 89         update(add[i+1],add[i]-cnt_add[i]);
 90         update(mns[i+1],mns[i]-cnt_mns[i]);
 91         update(cnt_add[i+1],cnt_add[i]);
 92         update(cnt_mns[i+1],cnt_mns[i]);
 93     }
 94
 95     init();
 96     for(int i=2;i<2*len+1;i++)
 97     {
 98         int tmp = Mp[i];
 99         if(Ma[i] == '#')
100         {
101             int cur = i/2+1,L = (i-tmp)/2+1, R = (i+tmp)/2-1,r = (tmp-1)/2;
102             add[cur] += cur-1;
103             mns[R+1] += cur - r - 1;
104             cnt_add[cur] ++;
105             cnt_mns[R+1] ++;
106         }else
107         {
108             int cur = i/2,L = (i-tmp)/2+1, R = (i+tmp)/2-1,r = 1+(tmp-1)/2;
109             add[cur] += cur;
110             mns[R+1] += cur-r;
111             cnt_add[cur] ++;
112             cnt_mns[R+1] ++;
113         }
114     }
115     for(int i=1;i<=len;i++)
116     {
117         update(cntR[i],add[i]-mns[i]);
118         update(add[i+1],add[i]-cnt_add[i]);
119         update(mns[i+1],mns[i]-cnt_mns[i]);
120         update(cnt_add[i+1],cnt_add[i]);
121         update(cnt_mns[i+1],cnt_mns[i]);
122     }
123     ans = 0;
124     for(int i=1;i<=len;i++)
125     {
126         update(ans,(cntR[i]*cntL[i+1])%MOD);
127     }
128 }
129
130 int main()
131 {
132     //freopen("1005.in","r",stdin);
133     while(true)
134     {
135         char c;
136         int len = 0;
137         while((c = getchar()) && isalpha(c))
138         {
139             line[len++] = c;
140         }
141         if(c == EOF) break;
142         Manacher(line,len);
143
144         memset(cntL,0,sizeof cntL);
145         memset(cntR,0,sizeof cntR);
146         solve(len);
147         printf("%I64d\n",(ans+MOD) % MOD);
148     }
149 }

转载于:https://www.cnblogs.com/helica/p/5742588.html

多校#5-1005-Instring-HDU5785-manacher+维护相关推荐

  1. 计算机组装与维护校本教材,《计算机组装及维护》校本教材.pdf

    [摘要]国家中等职业教育改革发展示范学校建设项目校本教材 计算机组装与维护 (修订稿) 主 编:李晓 副主编:永乾 安宁市职业高级中学 <计算机组装与维护>课程简介 作为职高学校的计算机专 ...

  2. 计算机信息管理面试自我介绍,信息管理专业的面试自我介绍

    在毕业的时候我们通常会要求写一份自我评价或自我鉴定,这些会放入自己的档案中,所以不能够随便写写,管理专业的自我评价范文,供参考. 大学四年中,我各方面的能力都得到了发展,可以说,经过大学四年的学习,我 ...

  3. 大学生计算机面试,大学生计算机毕业面试自我介绍

    大学生计算机毕业面试自我介绍 发布时间:2020-02-26 计算机专业在目前是比较需要的,那么你会自我介绍了吗,今天小编就给大家来分享一下面试自我介绍,好好参考哦 计算机专业应届生面试自我介绍 我学 ...

  4. 计算机如何自我介绍教程,2020计算机专业自我介绍4篇

    <2020计算机专业自我介绍4篇>由会员分享,可在线阅读,更多相关<2020计算机专业自我介绍4篇(6页珍藏版)>请在人人文库网上搜索. 1.2020计算机专业自我介绍4篇本文 ...

  5. android开发电话面试自我介绍,安卓开发面试自我介绍

    面试自我介绍既是面试中必备环节,也是求职者们最关心的问题之一.一个常规的面试,寒暄之后面试官提出的第一个问题几乎千篇一律:"请您简单地做一下自我介绍".有些被面试者都会问:简历中情 ...

  6. 计算机教师面试1分钟自我介绍视频,学校面试1分钟自我介绍

    在学校当中有时候也是进行面试的,我们在面试的时候是如何进行自我介绍的呢?以下是小编给大家整理的学校面试1分钟自我介绍,喜欢的过来一起分享吧. 学校面试1分钟自我介绍一 时光匆匆,转眼间,大学三年的美丽 ...

  7. 计算机应聘大学生自我介绍,大学生计算机毕业面试自我介绍

    计算机专业在目前是比较需要的,那么你会自我介绍了吗,今天小编就给大家来分享一下面试自我介绍,好好参考哦 计算机专业应届生面试自我介绍 我学习成绩优良,学风端正,学习刻苦努力,奋发向上.在认真完成自身学 ...

  8. 我的计算机专业作文,计算机专业自我介绍

    计算机专业自我介绍 发布时间:2021-01-07 [计算机专业自我介绍一] 大学四年中,我各方面的能力都得到了发展,可以说,经过大学四年的学习,我已经具备了适应社会工作的能力.这学期即将画上了句号, ...

  9. 面试时计算机工程自我介绍范文,计算机专业大学生面试自我介绍范文

    <计算机专业大学生面试自我介绍范文>由会员分享,可在线阅读,更多相关<计算机专业大学生面试自我介绍范文(5页珍藏版)>请在人人文库网上搜索. 1.计算机专业大学生面试自我介绍范 ...

最新文章

  1. 最新调查,48%的美国人表示不会乘坐自动驾驶汽车
  2. torch.tensordot()介绍
  3. php long2ip,php ip2long和long2ip函数实现
  4. [Java并发编程实战] 共享对象之可见性
  5. ML之Hash_HamMingDistance:基于输入图片哈希化(均值哈希+差值哈希)即8*8个元素的单向vector利用汉明距离算法进行判别
  6. 神策 FM | 关于定价的 10 年经验总结
  7. c语言基础回顾 —— 其他知识点
  8. UITextView
  9. 关于python开发CRM系统
  10. bzoj2437 [Noi2011]兔兔与蛋蛋
  11. python入门代码大全-python入门代码指南教程书籍推荐2020总结全集汇总
  12. 时间序列深度学习:状态 LSTM 模型预测太阳黑子(一)
  13. [C/C++11语法]_[0基础]_[lamba 表达式介绍]
  14. 制作自启动的MSDN简体中文版和英文版win98ISO镜像
  15. IGS发布RINEX 4.00
  16. ENVI用ROI进行裁剪
  17. 虚拟机设置共享文件夹之后看不见文件(失败合集+成功分享)
  18. 2022软件测试技能 Apache JMeter 性能测试从入门到精通
  19. Android开发之小程序-秒表
  20. oracle 帮助文件,oracle chm帮助文件下载

热门文章

  1. 从DOM到虚拟DOM——前端DOM发展史、性能与产能双赢背后的思考
  2. 学历影响程序员的工资吗?
  3. 关于TCP三次握手过程
  4. linux统计某个字符个数,Linux统计一个文件中特定字符个数的方法
  5. 测控技术与仪器专业c语言教学视频,测控技术与仪器要学哪些基础和专业课程...
  6. android 宽度动画,android – ObjectAnimator对LinearLayout宽度进行动画处理
  7. android 查找所有dialog_android 布局文件layout分组的简单使用
  8. 基本Linux命令的用法
  9. Python风格总结:面向对象
  10. 吴恩达深度学习5.2笔记_Sequence Models_自然语言处理与词嵌入