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
  • 相关阅读:
    前端页面的防抖与节流
    vue3.0 响应式原理
    cssBEM命名规范及常用CSS class 命名
    vue2.x 响应式原理
    npm 相关命令
    Node之 fs
    Node 之 Buffer
    Node之path
    Node之process
    Node.js 如何处理 ES6 模块
  • 原文地址:https://www.cnblogs.com/wjyi/p/5618459.html
Copyright © 2011-2022 走看看