zoukankan      html  css  js  c++  java
  • bzoj3796(后缀数组)(SA四连)

    bzoj3796Mushroom追妹纸

    题目描述

    Mushroom最近看上了一个漂亮妹纸。他选择一种非常经典的手段来表达自己的心意——写情书。考虑到自己的表达能力,Mushroom决定不手写情书。他从网上找到了两篇极佳的情书,打算选择其中共同的部分。另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子。
    Mushroom不希望自己的情书中完整的出现了情敌的情书。(这样抄袭的事情就暴露了)。
    Mushroom把两封情书分别用字符串s1和s2来表示,Ertanis的情书用字符串s3来表示,他要截取的部分用字符串w表示。
    需满足:
    1、w是s1的子串
    2、w是s2的子串
    3、s3不是w的子串
    4、w的长度应尽可能大
    所谓子串是指:在字符串中连续的一段。
    题解
    我真是有看见字符串想SAM综合征。。
    要求匹配的串只有两个,可以把它们连起来求一遍SA。
    然后KMP求出c在大串中出现的位置。
    维护一个数组f[i]表示从i位置开始至多延长多少个位置保证不包含c。
    然后扫两遍,一遍算第一个串对第二个串的贡献,再算第二个串对第一个串的贡献,滚动维护一下min(height)就好了。
    又TM开小数组了。、
    代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 200009
    using namespace std;
    int n,m,sa[N],rnk[N],tong[N],y[N],height[N],n1,fail[N],f[N],ans;
    bool b[N],tag[N];
    char s[N],s1[N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){
        m=200;
        for(int i=1;i<=n;++i)rnk[i]=s[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;m=p,w<<=1){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();swap(rnk,y);rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)rnk[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+w]==y[sa[i-1]+w]))?p:++p;
        }    
        for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(s[i+j]==s[sa[rnk[i]-1]+j])j++;
            height[rnk[i]]=j;
        }   
    }
    inline void check(int pos,int ln){
        int j=0;
        for(int i=pos;i<=pos+ln-1;++i){
            while(j&&s[i]!=s1[j+1])j=fail[j];
            if(s[i]==s1[j+1])j++;
            if(j==n1){cout<<"gan";return;}
        } 
        cout<<"yeah";
    }
    int main(){
        scanf("%s%s",s+1,s1+1);
        n=strlen(s+1);n1=strlen(s1+1);
        for(int i=1;i<=n;++i)f[i]=n-i+1;s[++n]='#'; 
        for(int i=1;i<=n1;++i)s[++n]=s1[i],b[n]=1,f[n]=n1-i+1;
        SA();
        scanf("%s",s1+1);n1=strlen(s1+1);
        int j=0;
        for(int i=2;i<=n1;++i){
            while(j&&s1[i]!=s1[j+1])j=fail[j];
            if(s1[i]==s1[j+1])j++;fail[i]=j;
        }
        j=0;
        for(int i=1;i<=n;++i){
            while(j&&s[i]!=s1[j+1])j=fail[j];
            if(s[i]==s1[j+1])j++;
            if(j==n1)tag[i-j+1]=1;
        }
        int xian=n+1;
        for(int i=n;i>=1;--i){
            if(tag[i])xian=min(xian,i+n1-1);
            f[i]=min(f[i],xian-i);
        }
        xian=0;
        for(int i=1;i<=n;++i){
            int pos=sa[i];
            if(!b[pos])xian=min(xian,height[i]),ans=max(ans,min(f[pos],xian));
            else xian=2e9;
        }
        xian=0;
        for(int i=1;i<=n;++i){
            int pos=sa[i];
            if(b[pos])xian=min(xian,height[i]),ans=max(ans,min(f[pos],xian));
            else xian=2e9;
        }
        cout<<ans;
        return 0;
    } 
    View Code
    SA四连
    bzoj1692队列变换
    FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”。在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过。 今年,竞赛委员会在接受队伍报名时,采用了一种新的登记规则:他们把所有队伍中奶牛名字的首字母取出,按它们对应奶牛在队伍中的次序排成一列(比如说,如果FJ带去的奶牛依次为Bessie、Sylvia、Dora,登记人员就把这支队伍登记为BSD)。登记结束后,组委会将所有队伍的登记名称按字典序升序排列,就得到了他们的出场顺序。 FJ最近有一大堆事情,因此他不打算在这个比赛上浪费过多的时间,也就是说,他想尽可能早地出场。于是,他打算把奶牛们预先设计好的队型重新调整一下。 FJ的调整方法是这样的:每次,他在原来队列的首端或是尾端牵出一头奶牛,把她安排到新队列的尾部,然后对剩余的奶牛队列重复以上的操作,直到所有奶牛都被插到了新的队列里。这样得到的队列,就是FJ拉去登记的最终的奶牛队列。 接下来的事情就交给你了:对于给定的奶牛们的初始位置,计算出按照FJ的调整规则所可能得到的字典序最小的队列。
    每次只有两种选择,从前拿和从后拿,判断这个需要字典序,用后缀数组就好了。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 210002
    using namespace std;
    int n,m,rnk[N],y[N],tong[N],sa[N],top;
    char s[N],zh[N],c[1];
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){    
        m=300;
        for(int i=1;i<=n;++i)rnk[i]=s[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;m=p,w<<=1){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();
            swap(rnk,y);
            rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)rnk[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+w]==y[sa[i-1]+w]))?p:++p;
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%s",c),s[i]=c[0];
        int zu=n;
        s[++n]='#';
        for(int i=zu;i>=1;--i)s[++n]=s[i];
        SA();
        int p=1,q=zu+2,pp=1,qq=zu,cnt=0;
        for(int i=1;i<=zu;++i){
            if(rnk[p]<rnk[q]){printf("%c",s[pp]);pp++;p++;}
            else{printf("%c",s[qq]);qq--;q++;}
           cnt++;if(cnt==80)puts(""),cnt=0;
       }
        return 0; 
    } 
    View Code

    牛奶模式Milk Patterns

    农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

    SA完后用单调队列维护一下长度为k的最小值就可以了。

    #include<iostream>
    #include<cstdio>
    #define N 100002
    #define M 1000002
    using namespace std;
    int n,m,tong[M],sa[N],rnk[N],y[N],a[N],k,h,t,q[N],height[N],ans;
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x; 
    }
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){
        for(int i=1;i<=n;++i)rnk[i]=a[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;w<<=1,m=p){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();swap(rnk,y);rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)rnk[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+w]==y[sa[i]+w])?p:++p; 
        }
        for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(a[i+j]==a[sa[rnk[i]-1]+j])j++;
            height[rnk[i]]=j;
        }
    }
    int main(){
        n=rd();k=rd();k--;
        for(int i=1;i<=n;++i)a[i]=rd(),m=max(m,a[i]);
        SA();h=1;t=0;
        for(int i=2;i<=n;++i){
            while(h<=t&&q[h]<i-k+1)h++;
            while(h<=t&&height[i]<=height[q[t]])t--;
            q[++t]=i;
            if(i>=2+k-1)ans=max(ans,height[q[h]]);
        }
        cout<<ans;
        return 0;
    } 
    View Code

    bzoj2946[Poi2000]公共串

    求n个串的最长公共子串。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define N 50002
    using namespace std;
    int n,m,tong[N],sa[N],rnk[N],y[N],height[N],ans,p[20][N],len,tag[N],ji[10],num;
    char s[N],s1[N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x; 
    }
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){
        m=200;
        for(int i=1;i<=n;++i)rnk[i]=s[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;w<<=1,m=p){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();swap(rnk,y);rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)rnk[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+w]==y[sa[i]+w])?p:++p; 
        }
        for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(s[i+j]==s[sa[rnk[i]-1]+j])j++;
            height[rnk[i]]=j;
            p[0][rnk[i]]=j;
        }
        for(int i=1;(1<<i)<=n;++i)
          for(int j=1;j+(1<<i)-1<=n;++j)p[i][j]=min(p[i-1][j],p[i-1][j+(1<<i-1)]);
    }
    inline int RMQ(int l,int r){
        int x=log2(r-l+1);
        return min(p[x][l],p[x][r-(1<<x)+1]);
    }
    int main(){
        num=rd();
        for(int i=1;i<=num;++i){
            scanf("%s",s1+1);len=strlen(s1+1);
            for(int j=1;j<=len;++j)s[++n]=s1[j],tag[n]=i;s[++n]=i;
        }
        SA();
        for(int i=1;i<=n;++i){
            int id=sa[i];
            ji[tag[id]]=i;int nn=2e9;
            for(int j=1;j<=num;++j)nn=min(nn,ji[j]);
            if(!nn)continue;
            ans=max(ans,RMQ(nn+1,i));
        }
        cout<<ans;
        return 0;
    } 
    View Code

    bzoj3230相似子串

    我们可以维护一个数组sum表示前i名后缀能够产生的本质不同的子串。

    然后确定第i个子串可以用二分。

    求公共后缀那块可以搞一个反着的后缀数组。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #define N 100002
    #define pa pair<int,int>
    #define mm make_pair
    using namespace std;
    typedef long long ll;
    ll ans;
    int n,m,tong[N],y[N],q;
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x; 
    }
    struct suffixarray{
        int sa[N],rnk[N],p[19][N],height[N];
        ll sum[N]; 
        char s[N];
        inline void qsort(){
          for(int i=0;i<=m;++i)tong[i]=0;
          for(int i=1;i<=n;++i)tong[rnk[i]]++;
          for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
          for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
        }
        inline void build(){
          m=300;
          for(int i=1;i<=n;++i)rnk[i]=s[i],y[i]=i;
          qsort();
          for(int w=1,p=0;p<n;w<<=1,m=p){
             p=0;
             for(int i=n-w+1;i<=n;++i)y[++p]=i;
             for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
             qsort();swap(rnk,y);rnk[sa[1]]=p=1;
             for(int i=2;i<=n;++i)rnk[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+w]==y[sa[i]+w])?p:++p; 
           }
          for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(s[i+j]==s[sa[rnk[i]-1]+j])j++;
            height[rnk[i]]=j;
            p[0][rnk[i]]=j;
          }
          for(int i=1;(1<<i)<=n;++i)
            for(int j=1;j+(1<<i)-1<=n;++j)p[i][j]=min(p[i-1][j],p[i-1][j+(1<<i-1)]);    
            for(int i=1;i<=n;++i)sum[i]=sum[i-1]+n-sa[i]+1-height[i];
        }
        inline pa get(ll x){
            int l=1,r=n;ll ans1,ans2;
            if(sum[n]<x)return mm(-1,-1);
            while(l<=r){
                int mid=(l+r)>>1;
                if(sum[mid]>=x){ans1=mid;ans2=n-sa[mid]+1-(sum[mid]-x);r=mid-1;}
                else l=mid+1;
            }
            return mm(ans1,ans2);
        }
        inline int RMQ(int l,int r){
            if(l>r)return 2e9;
            int lo=log2(r-l+1);
            return min(p[lo][l],p[lo][r-(1<<lo)+1]);
        }
    }sa1,sa2;
    int main(){
        n=rd();q=rd();
        scanf("%s",sa1.s+1);
        for(int i=1;i<=n;++i)sa2.s[i]=sa1.s[n-i+1];
        sa1.build();sa2.build();ll x,y;
        while(q--){
            x=rd();y=rd();ans=0;
            pa xx=sa1.get(x),yy=sa1.get(y);
            if(yy.first<0){printf("-1
    ");continue;}
            ll zz=sa1.RMQ(xx.first+1,yy.first);//cout<<zz<<endl;
            zz=min(zz,(ll)min(yy.second,xx.second));
            ans+=zz*zz;
            xx.first=sa2.rnk[n-sa1.sa[xx.first]+2-xx.second]; 
            yy.first=sa2.rnk[n-sa1.sa[yy.first]+2-yy.second]; 
            zz=sa2.RMQ(min(xx.first,yy.first)+1,max(yy.first,xx.first));
            zz=min(zz,(ll)min(yy.second,xx.second));
            ans+=zz*zz;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    POJ1743Musical Them

    给一个数串,求串内有最长的子串,它出现了不止一次且存在两次出现的位置不相交。
    这道题的限制条件比较多,不好直接做,考虑答案具有单调性,可以选择二分答案。

    然后扫一遍height数组,把height>=mid分成若干联通块,块内维护posmin和posmax,若posmax-posmin>=mid则找到一组合法解。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 20009
    #define inf 2e9
    using namespace std;
    int n,m,tong[N],rnk[N],sa[N],a[N],y[N],height[N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){
        m=200;
        for(int i=1;i<=n;++i)rnk[i]=a[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;m=p,w<<=1){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();swap(rnk,y);
            rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)
              rnk[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+w]==y[sa[i-1]+w]))?p:++p;
        }
        for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(a[i+j]==a[sa[rnk[i]-1]+j])++j;
            height[rnk[i]]=j;
        } 
    }
    inline bool check(int mid){
        int ma=-inf,mi=inf;
        for(int i=1;i<=n;++i){
            if(height[i]<mid){
                ma=-inf;mi=inf;
            }
            else{
                ma=max(ma,sa[i]);mi=min(mi,sa[i]);
                ma=max(ma,sa[i-1]);mi=min(mi,sa[i-1]);
                if(ma-mi>=mid)return 1; 
            }
        }
        return 0;
    }
    int main(){
       while(1){
             n=rd();if(!n)return 0;
             memset(a,0,sizeof(a));
             memset(rnk,0,sizeof(rnk));
             memset(sa,0,sizeof(sa));
             for(int i=1;i<=n;++i)a[i]=rd();
             for(int i=1;i<n;++i)a[i]=a[i+1]-a[i]+100;a[n]=0;
            n--;
             SA();
          int l=4,r=n,ans=-1;
          while(l<=r){
              int mid=(l+r)>>1;
              if(check(mid))ans=mid,l=mid+1;else r=mid-1;
          }
        printf("%d
    ",ans+1);
       }
       return 0;    
    }
    View Code

    POJ3145

    给两个串,求这两个串大于k的公共子串数量。

    这个和那道省选题(找相同字符)基本是一道题。

    先求出height数组,然后维护一个单调上升的单调栈,维护一个num,一个cnt,统计答案就好了。

    注意,在压栈时,压的是i-1而不是i。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 200002
    using namespace std;
    typedef long long ll;
    int m,n,rnk[N],height[N],y[N],tong[N],tag[N],sa[N],k,n1,n2,top;
    ll ans,num,st[N],cnt[N];
    char s[N],s1[N],s2[N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    inline void qsort(){
        for(int i=0;i<=m;++i)tong[i]=0;
        for(int i=1;i<=n;++i)tong[rnk[i]]++;
        for(int i=1;i<=m;++i)tong[i]+=tong[i-1];
        for(int i=n;i>=1;--i)sa[tong[rnk[y[i]]]--]=y[i];
    }
    inline void SA(){
        m=1000;
        for(int i=1;i<=n;++i)rnk[i]=s[i],y[i]=i;
        qsort();
        for(int w=1,p=0;p<n;m=p,w<<=1){
            p=0;
            for(int i=n-w+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>w)y[++p]=sa[i]-w;
            qsort();swap(rnk,y);
            rnk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)
              rnk[sa[i]]=((y[sa[i]]==y[sa[i-1]])&&(y[sa[i]+w]==y[sa[i-1]+w]))?p:++p;
        }
        for(int i=1;i<=n;++i){
            if(rnk[i]==1)continue;
            int j=max(0,height[rnk[i-1]]-1);
            while(s[i+j]==s[sa[rnk[i]-1]+j])++j;
            height[rnk[i]]=j;
        } 
    }
    int main(){
        while(1){
            k=rd();if(!k)break;
            scanf("%s%s",s1+1,s2+1);n1=strlen(s1+1);n2=strlen(s2+1);
            for(int i=1;i<=n1;++i)s[i]=s1[i],tag[i]=1;
            for(int i=1;i<=n2;++i)s[n1+1+i]=s2[i],tag[n1+1+i]=2;s[n1+1]='&';
            n=n1+n2+1;s[n+1]=0;
            memset(height,0,sizeof(height));
            SA();
            for(int i=1;i<=n;++i)height[i]-=k-1;ans=top=0;
            top=num=0;
            for(int i=1;i<=n;++i){
                int ji=tag[sa[i-1]]==1?0:1;
                while(top&&st[top]>=height[i])num-=st[top]*cnt[top],ji+=cnt[top],top--;
                if(height[i]>0)st[++top]=height[i],cnt[top]=ji;num+=cnt[top]*st[top]; 
                if(tag[sa[i]]==1)ans+=num;
            }
            top=num=0;
            for(int i=1;i<=n;++i){
                int ji=tag[sa[i-1]]==2?0:1;
                while(top&&st[top]>=height[i])num-=st[top]*cnt[top],ji+=cnt[top],top--;
                if(height[i]>0)st[++top]=height[i],cnt[top]=ji;num+=cnt[top]*st[top];
                if(tag[sa[i]]==2)ans+=num;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    串行与并行
    并发性和并行性
    循环移位操作
    关于指针
    各种编程语言的特点
    什么是面向过程,什么是面向对象?
    数组指针/指针数组的示例
    数组指针/指针数组
    操作系统判断
    springMVC---简介
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10238906.html
Copyright © 2011-2022 走看看