1524: [POI2006]Pal
Time Limit: 5 Sec Memory Limit: 357 MB
Submit: 367 Solved: 121
Description
给出n个回文串s1, s2, …, sn 求如下二元组(i, j)的个数 si + sj 仍然是回文串 规模 输入串总长不超过2M bytes
Input
The first line of input file contains the number of strings n. The following n lines describe each string: The i+1-th line contains the length of the i-th string li, then a single space and a string of li small letters of English alphabet. You can assume that
the total length of all strings will not exceed 2,000,000. Two strings in different line may be the same.
Output
Print out only one integer, the number of palindromes
Sample Input
6
2 aa
3 aba
3 aaa
6 abaaba
5 aaaaa
4 abba
Sample Output
14
Trie+哈希随便搞搞就行了。
#SXOI2016之蜜汁错误# 考场上忘记每个串都是回文串,想复杂了,最后只拿了30,剩下70全部TLE。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstring> #include<algorithm> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define ull unsigned long long #define maxn 2000005 #define base 233 using namespace std; int n,tot=1; int l[maxn],cnt[maxn],num[maxn],t[maxn][26]; ll ans; ull ha[maxn],p[maxn]; char ch[maxn]; string s[maxn]; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { p[0]=1;F(i,1,2000000) p[i]=p[i-1]*base; n=read(); F(i,1,n) { l[i]=read(); scanf("%s",ch);s[i]=ch; //字符串这样读入更快 // cin>>s[i]; //TLE int now=1;ull tmp=0; F(j,0,l[i]-1) { int x=s[i][j]-'a'; if (!t[now][x]) t[now][x]=++tot; now=t[now][x]; tmp=tmp*base+(ull)(x+1); } cnt[now]++;num[now]=i;ha[i]=tmp; } F(i,1,n) { int now=1; F(j,0,l[i]-1) { now=t[now][s[i][j]-'a']; if (cnt[now]&&ha[num[now]]*p[l[i]]+ha[i]==ha[i]*p[l[num[now]]]+ha[num[now]]) ans+=cnt[now]; } } ans=ans*2-n; printf("%lld\n",ans); return 0; }
时间: 2024-12-29 11:32:33