2012SCAU校赛题

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.

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

ABC
ABABA
AABB

Sample Output

0
7
2

Author

ick2

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 200002
int 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;
}


资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值