2012SCAU校赛题
来源:互联网 发布:bedook祛痘怎么样知乎 编辑:程序博客网 时间:2024/06/15 22:16
E. Prefix Sum
Time Limit : 6000/3000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 115 Accepted Submission(s) : 30
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
A string v is a suffix string of a string w if string v can read from a position of string w and to the end of w.
For example, string bc is a suffix string of abc. but ab is not.
A string v is a prefix string of a string w if string v can read from the beginning of string w.
For example, string ab is prefix string of string abc, but bc and abcd are not.
For 2 strings s1 and s2, if there is a string s3 is both the prefix of s1 and s2, we call s3 is a common prefix of s1 and s2.
The longest common prefix of 2 strings is the longest common prefix string of all the common prefix strings among these 2 strings.
Your task is:
Give you the string, count the sum of the length of each of the longest common prefix string of each 2 suffix of the string.
For example, string bc is a suffix string of abc. but ab is not.
A string v is a prefix string of a string w if string v can read from the beginning of string w.
For example, string ab is prefix string of string abc, but bc and abcd are not.
For 2 strings s1 and s2, if there is a string s3 is both the prefix of s1 and s2, we call s3 is a common prefix of s1 and s2.
The longest common prefix of 2 strings is the longest common prefix string of all the common prefix strings among these 2 strings.
Your task is:
Give you the string, count the sum of the length of each of the longest common prefix string of each 2 suffix of the string.
Input
There are multi strings. One string per line. Each string is no longer than 10^5. The strings only contain A-Z and a-z.
Output
For each string, output the sum.
Sample Input
ABCABABAAABB
Sample Output
072
Author
Source
SCAUCPC 2012
这题是校赛两题放AK的题之一,题意是求一个字符串的所有后缀之间的最长前缀的总和,当时敲好后缀数组模板后发现我想错了,当时最优的想也是O(n^2),会tle,好像剪剪就能过去了,今天剪过去了,400+ms,正解是单调栈处理,当时不会做,比赛后想了很久都不知道单调栈要怎么操作,今天切dp的时候发现了dp可以解这类单调栈的问题,就是一个很简单的转移,方法近乎O(n),100+ms过了,好快,如果用dc3可能更快,转移的重点
for(int i=len;i>=0;i--)
{
while(d[i]<len&&height[i]<=height[d[i]+1])
d[i]=d[d[i]+1];
}
这个转好像有两个for,其实复杂度几乎O(n),标记这个height值可以到最右边的位置,这样我们每次统计就可以用一段来统计,中间跳转,速度很快。
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <string>#include <queue>#include <cmath>#include <stack>#define LG long long#define FOR(i,a,n) for(int i=a;i<n;++i)#define REP(i,n) FOR(i,0,n)using namespace std;#define maxn 200002int wa[maxn],wb[maxn],wv[maxn],wc[maxn];int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m){ int *x=wa,*y=wb,*t; REP(i,m) wc[i]=0; REP(i,n) wc[x[i]=r[i]]++; FOR(i,1,m) wc[i]+=wc[i-1]; for(int i=n-1;i>=0;i--) sa[--wc[x[i]]]=i; for(int j=1,p=1;p<n;j*=2,m=p) { p=0; for(int i=n-j;i<n;i++) y[p++]=i; REP(i,n) if(sa[i]>=j) y[p++]=sa[i]-j; REP(i,n) wv[i]=x[y[i]]; REP(i,m) wc[i]=0; REP(i,n) wc[wv[i]]++; FOR(i,1,m) wc[i]+=wc[i-1]; for(int i=n-1;i>=0;i--) sa[--wc[wv[i]]]=y[i]; swap(x,y); p=1,x[sa[0]]=0; for(int i=1;i<n;i++) x[sa[i]] = cmp( y, sa[i-1], sa[i], j)?p-1:p++; } return;}int rk[maxn],height[maxn];void calheight(int *r,int *sa,int n){ int i,j,k=0; for(i=1;i<=n;i++) rk[sa[i]]=i; for(i=0;i<n;height[rk[i++]]=k) for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); return;}char s[maxn];int r[maxn],sa[maxn],h[maxn],d[maxn];int main(){ while(~scanf("%s",s)) { int len=strlen(s); for(int i=0;i<len;i++) { r[i]=s[i];d[i]=i; }d[len]=len; r[len]=0; da(r,sa,len+1,256); calheight(r,sa,len); int ans=0; for(int i=len;i>=0;i--){while(d[i]<len&&height[i]<=height[d[i]+1])d[i]=d[d[i]+1];} for(int i=0;i<=len;i++) {if(height[i]==0)continue;int bin=i,flag=i; while(bin<=len){ans+=height[bin]*(d[bin]-flag+1);flag=bin=d[bin]+1;} } printf("%d\n",ans); } return 0;}
- 2012SCAU校赛题
- SCAU F 寻找SCAU
- scau 10306 Prison break
- SCAU 8615 快乐
- scau 10345 前缀平均值
- SCAU A 一起来填数吧
- SCAU B 体育课
- scau 11075 强盗分赃
- scau 9714 圣诞礼物
- 参与SCAU-12级网赛总结
- SCAU 1142 巡逻的士兵
- scau 1079 三角形(暴力)
- scau 9716 矩形的并
- SCAU C Sheep回文串
- scau 2011 校赛 10311 List Expression
- SCAU 11162 Acmer入门之道
- SCAU OJ 9715 相邻最大矩形面积
- SCAU Individual Contest #1 (未更新完)
- camera接口介绍
- 问题
- SQLLoader学习示例1
- 俄罗斯方块准备起航
- bean标签
- 2012SCAU校赛题
- curl实现配置host
- synthesize只有一个变量指针 不会分配空间
- MS SQL Serve中的.mdf和.ldf
- sql 2008注入经验
- Android 利用【Hierarchy Viewer 】 工具学习别人的UI设计
- 谷歌浏览器扩展程序开发教程之创建你的第一个扩展程序
- WP7 pin to start 自定义应用程序的Tile
- 三天一结