没有题面差评

先来遍SA求出h,再给h排序,从大到小计算,并查集维护连续的区间(表达能力太弱。。还是看代码好说话)

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e18
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define NM 300000+5
10 using namespace std;
11 ll read(){
12     ll x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 char st[NM];
18 int n,m,tmp[NM],top[NM],sa[NM],h[NM],rank[NM];
19 ll f[NM],mx[NM],mn[NM],size[NM],ans[NM],_ans[NM];
20 bool cmp(int x,int y){
21     return h[x]>h[y];
22 }
23 void getsa(){
24     int j;m=256;
25     inc(i,0,n)top[rank[i]=(int)st[i]]++;
26     inc(i,1,m)top[i]+=top[i-1];
27     inc(i,0,n)sa[--top[rank[i]]]=i;
28     for(int k=1;k<=n;k<<=1){
29         inc(i,0,n){
30             j=sa[i]-k;
31             if(j<0)j+=n+1;
32             tmp[top[rank[j]]++]=j;
33         }
34 //        inc(i,0,n)printf("%d ",tmp[i]);printf("\n");
35         sa[tmp[top[0]=0]]=j=0;
36         inc(i,1,n){
37             if(rank[tmp[i]]!=rank[tmp[i-1]]||rank[tmp[i]+k]!=rank[tmp[i-1]+k])
38             top[++j]=i;
39             sa[tmp[i]]=j;
40         }
41         memcpy(rank,sa,sizeof(sa));
42         memcpy(sa,tmp,sizeof(tmp));
43     }
44     j=0;
45     inc(i,0,n)if(rank[i]){
46         if(j)j--;
47         while(st[i+j]==st[sa[rank[i]-1]+j])j++;
48         h[rank[i]]=j;
49     }
50 }
51 int find(int x){
52     return f[x]==x?x:f[x]=find(f[x]);
53 }
54 int main(){
55     freopen("data.in","r",stdin);
56     n=read();
57     scanf("%s",st);
58     st[n]='$';
59     inc(i,0,n-1)mx[i]=mn[i]=read();
60     getsa();
61     inc(i,0,n-1)f[i]=i,tmp[i]=i+1,size[i]=1;
62     sort(tmp+1,tmp+n+1,cmp);
63     inc(i,0,n-1)_ans[i]=-inf;
64 //    inc(i,1,n)printf("%d ",h[tmp[i]]);printf("\n");
65     inc(i,1,n){
66         int x=find(sa[tmp[i]]),y=find(sa[tmp[i]-1]);
67         if(x==y)continue;
68         ans[h[tmp[i]]]+=(ll)size[x]*size[y];
69         _ans[h[tmp[i]]]=max(_ans[h[tmp[i]]],max((ll)mx[x]*mx[y],(ll)mn[x]*mn[y]));
70         f[y]=x;size[x]+=size[y];
71         mx[x]=max(mx[x],mx[y]);
72         mn[x]=min(mn[x],mn[y]);
73     }
74     dec(i,n-2,0)if(ans[i+1])ans[i]+=ans[i+1],_ans[i]=max(_ans[i],_ans[i+1]);
75     inc(i,0,n-1)if(!ans[i])_ans[i]=0;
76     inc(i,0,n-1)printf("%lld %lld\n",ans[i],_ans[i]);
77     return 0;
78 }
View Code

 

posted on 2016-02-11 23:01  onlyRP  阅读(135)  评论(0编辑  收藏  举报