zoukankan      html  css  js  c++  java
  • BZOJ4199: [Noi2015]品酒大会

    后缀数组height排序后并查集合并

    也就是height较大的合并不影响较小的

    num[i]=num[i+1]  ans[i]=ans[i+1]

    合并时,num+=sz[x]*sz[y],ans=max(mn[x]*mn[y],mx[x]*mx[y],ans)

    这种思路适应于求点对,还可以考虑启发式合并

    后缀数组还有的常见思路就是二分,height分组

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 300005
     4 #define ll long long
     5 ll sum[N],ans[N];
     6 int n,val[N],fa[N],mx[N],mn[N],sz[N];
     7 int m=256,c[N],sa[N],rk[N],h[N],t1[N],t2[N];
     8 char s[N];
     9 struct Node{
    10   int h,x,y;
    11 }g[N];
    12 int find(int x){
    13   return fa[x]==x?x:fa[x]=find(fa[x]);
    14 }
    15 void get_sa(int n){
    16   int *x=t1,*y=t2;
    17   for(int i=0;i<m;i++)c[i]=0;
    18   for(int i=0;i<n;i++)c[x[i]=s[i]]++;
    19   for(int i=0;i<m;i++)c[i]+=c[i-1];
    20   for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    21   for(int k=1;k<=n;k<<=1){
    22     int p=0;
    23     for(int i=n-k;i<n;i++)y[p++]=i;
    24     for(int i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
    25     for(int i=0;i<m;i++)c[i]=0;
    26     for(int i=0;i<n;i++)c[x[y[i]]]++;
    27     for(int i=0;i<m;i++)c[i]+=c[i-1];
    28     for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
    29     swap(x,y);x[sa[0]]=0;p=1;
    30     for(int i=1;i<n;i++)
    31       x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
    32     if(p>=n)break;
    33     m=p;
    34   }
    35 }
    36 void get_height(int n){
    37   for(int i=0;i<n;i++)rk[sa[i]]=i;
    38   int k=0;
    39   for(int i=0;i<n;i++){
    40     if(k)k--;
    41     int j=sa[rk[i]-1];
    42     while(s[i+k]==s[j+k])k++;
    43     h[rk[i]]=k;
    44   }
    45 }
    46 bool cmp(Node x,Node y){
    47   return x.h>y.h;
    48 }
    49 void unite(int x,int y){
    50   fa[x]=y;
    51   sz[y]+=sz[x];
    52   mn[y]=min(mn[y],mn[x]);
    53   mx[y]=max(mx[y],mx[x]);
    54 }
    55 int main(){
    56   scanf("%d",&n);
    57   scanf("%s",s);
    58   for(int i=1;i<=n;i++)scanf("%d",&val[i]);
    59   get_sa(n+1);
    60   get_height(n+1);
    61   for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1,mx[rk[i-1]]=mn[rk[i-1]]=val[i];
    62   for(int i=1;i<n;i++)g[i].h=h[i+1],g[i].x=i+1,g[i].y=i; 
    63   sort(g+1,g+n,cmp);
    64   memset(sum,128,sizeof(sum));
    65   for(int i=g[1].h,j=1;i>=0;i--){
    66     ans[i]=ans[i+1],sum[i]=sum[i+1];
    67     for(;j<n&&g[j].h==i;j++){
    68       int x=find(g[j].x),y=find(g[j].y);
    69       sum[i]=max(sum[i],1ll*mx[x]*mx[y]);
    70       sum[i]=max(sum[i],1ll*mn[x]*mn[y]);
    71       ans[i]+=1ll*sz[x]*sz[y];
    72       unite(x,y);
    73     }
    74   }
    75   for(int i=0;i<n;i++)printf("%lld %lld
    ",ans[i],ans[i]==0?0:sum[i]);
    76   return 0;
    77 }
    View Code
  • 相关阅读:
    陶瓷电容的结构、工艺、失效模式
    Vue.js最佳实践
    Vue 超快速学习
    CSS 小技巧
    HTML5 Canvas
    webkit下面的CSS设置滚动条
    Some untracked working tree files would be overwritten by checkout. Please move or remove them before you can checkout. View them
    JSCS: Please specify path to 'JSCS' package
    React中ref的使用方法
    React 60S倒计时
  • 原文地址:https://www.cnblogs.com/wjyi/p/5618459.html
Copyright © 2011-2022 走看看