bzoj4199&uoj131: [Noi2015]品酒大会
2015-08-16 16:23
302 查看
传送门:http://uoj.ac/problem/131
思路:先求出height,然后根据排名重新给后缀标号,按height从大到小做,每次合并i和i-1,用并查集维护,更新答案。
思路:先求出height,然后根据排名重新给后缀标号,按height从大到小做,每次合并i和i-1,用并查集维护,更新答案。
#include<cstdio> #include<cstring> #include<algorithm> #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const int maxn=300010; using namespace std; typedef long long ll; int n,a[maxn];ll ans[maxn],cnt[maxn];char s[maxn]; struct orz{int h,pos;}cls[maxn]; bool cmp(orz a,orz b){return a.h>b.h;} struct Tufs{ int maxs[maxn],mins[maxn],fa[maxn],siz[maxn]; int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);} void merge(int x,int y){ x=getfa(x),y=getfa(y),fa[y]=x; maxs[x]=max(maxs[x],maxs[y]); mins[x]=min(mins[x],mins[y]); siz[x]+=siz[y]; } }ufs; struct Suffix_Array{ int sa[maxn],rank[maxn],t1[maxn],t2[maxn],sum[maxn],h[maxn]; void getsa(){ int *x=t1,*y=t2,m=255,p=0; for (int i=1;i<=n;i++) sum[x[i]=s[i]]++; for (int i=1;i<=m;i++) sum[i]+=sum[i-1]; for (int i=n;i;i--) sa[sum[x[i]]--]=i; for (int j=1;p<n;j<<=1,m=p){ p=0; for (int i=n-j+1;i<=n;i++) y[++p]=i; for (int i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j; memset(sum,0,sizeof(sum)); for (int i=1;i<=n;i++) sum[x[y[i]]]++; for (int i=1;i<=m;i++) sum[i]+=sum[i-1]; for (int i=n;i;i--) sa[sum[x[y[i]]]--]=y[i]; swap(x,y),x[sa[1]]=p=1; for (int i=2;i<=n;i++){ if (y[sa[i]]!=y[sa[i-1]]||y[sa[i]+j]!=y[sa[i-1]+j]) p++; x[sa[i]]=p; } } memcpy(rank,x,sizeof(rank)); } void geth(){ for (int i=1,j=0;i<=n;i++){ if (rank[i]==1) continue; while (s[i+j]==s[sa[rank[i]-1]+j]) j++; h[rank[i]]=j; if (j) j--; } } void work(){ memset(ans,128,sizeof(ans)); for (int i=2;i<=n;i++) cls[i-1]=(orz){h[i],i}; sort(cls+1,cls+n,cmp); for (int i=cls[1].h,j=1;i>=0;i--){ ans[i]=ans[i+1],cnt[i]=cnt[i+1]; for (;j<n&&cls[j].h==i;j++){ int x=ufs.getfa(cls[j].pos),y=ufs.getfa(cls[j].pos-1); ans[i]=max(ans[i],1ll*ufs.maxs[x]*ufs.maxs[y]); ans[i]=max(ans[i],1ll*ufs.mins[x]*ufs.mins[y]); cnt[i]+=1ll*ufs.siz[x]*ufs.siz[y]; ufs.merge(x,y); } } for (int i=0;i<n;i++) if (cnt[i]) printf("%lld %lld\n",cnt[i],ans[i]); else puts("0 0"); } }SA; int main(){ scanf("%d%s",&n,s+1); for (int i=1;i<=n;i++) scanf("%d",&a[i]); SA.getsa(),SA.geth(); for (int i=1;i<=n;i++) ufs.fa[i]=i,ufs.mins[SA.rank[i]]=ufs.maxs[SA.rank[i]]=a[i],ufs.siz[i]=1; SA.work(); return 0; }
相关文章推荐
- Codeforces Round 459 D. Pashmak and Parmida's problem 树状数组求逆序数 变形
- 广度优先搜索
- Hive启动报错无法找到class— java.lang.NoClassDefFoundError
- html5新特性总结
- hdu1081 To the Max
- COJ 1287 求匹配串在模式串中出现的次数
- NOIP 2010 导弹拦截 排序+贪心
- mysql内置函数汇总
- 66 Plus One
- IO模型
- HDU 2602 Bone Collector
- 论文中如何让页眉上自动显示章节标题
- hdu 2955 Robberies(0/1背包)
- 【LeetCode】107 - Binary Tree Level Order Traversal II
- 《C和指针(Pointer on c)》 学习笔记(转自:http://dsqiu.iteye.com/blog/1687944)
- JavaWeb项目中WEB-INF目录下class文件自动生成以及显示
- ACM之java 输入输出优化
- LeetCode题解2.1.6
- CSS3 timing-function: steps()介绍
- 简析——SQL注入