• poj 3415


    对拍没错。。莫名wa了

    利用容斥求每个串的重复子串

    其实就是找到每个元素能扩展到的最大元素

    即(rr-i)*(i-lr)*(w[i]-kk) 就可以了

    然后处理这个先离散化再搞

    另外是x y要清空

    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const ll N=2e5+1000;
    const double pi=acos(-1.0);
    ll height[N],rank[N],sa[N],c[N],x[N],y[N],a[N],n,m,kk;
    char s[N];
    void asa(ll n,ll m)
    {
      memset(x,0,sizeof(x));
      memset(y,0,sizeof(y)); 
      ll p=0,f=0;
      for (ll i=1;i<=m;i++) c[i]=0;
      for (ll i=1;i<=n;i++) c[x[i]=a[i]]++;
      for (ll i=1;i<=m;i++) c[i]+=c[i-1];
      for (ll i=n;i;i--) sa[c[x[i]]--]=i;
      for(ll i=1;i<=n&&p<=n;i<<=1)
      {
         p=0;
         for (ll j=n-i+1;j<=n;j++) y[++p]=j;
         for (ll j=1;j<=n;j++) 
           if (sa[j]>i) y[++p]=sa[j]-i;
         for (ll j=1;j<=m;j++) c[j]=0;
         for (ll j=1;j<=n;j++) c[x[y[j]]]++;
         for (ll j=1;j<=m;j++) c[j]+=c[j-1];
         for (ll j=n;j;j--) sa[c[x[y[j]]]--]=y[j];
         swap(x,y); x[sa[1]]=1; p=2;
         for (ll j=2;j<=n;j++)
           x[sa[j]]=y[sa[j]]==y[sa[j-1]]&&y[sa[j]+i]==y[sa[j-1]+i]
           ?p-1:p++;
         m=p;
      } 
      for (ll i=1;i<=n;i++) rank[sa[i]]=i;
      for (ll i=1;i<=n;i++)
      {
        ll j=sa[rank[i]-1];
        if (f) f--;
        while (a[i+f]==a[j+f]) f++;
        height[rank[i]]=f;
      }
    }
    struct re{
        ll a,b;
    };
    bool cmp(re x,re y)
    {
        return(x.a<y.a);
    }
    ll lr[N],rr[N];
    ll get_ans()
    {
      re a[N],b[N];
        for (ll i=1;i<=n;i++) 
          a[i].a=height[i],a[i].b=i;
        sort(a+1,a+1+n,cmp); 
        for (ll i=1;i<=n;i++)
          b[a[i].b].a=i,b[a[i].b].b=a[i].a;
        ll j;
        sort(a+1,a+1+n,cmp);
        b[0].a=-1; b[n+1].a=-1;
        for (ll i=1;i<=n;i++)
        {
              j=i-1;
            while (b[i].a<b[j].a) j=lr[j];
            lr[i]=j;
        }
        for (ll i=n;i>=1;i--)
        {
            j=i+1;
            while (b[i].a<b[j].a) j=rr[j];
            rr[i]=j;
        }
        ll ans=0;
        for (ll i=1;i<=n;i++)
          if (b[i].b>=kk) ans+=(b[i].b-kk+1)*(i-lr[i])*(rr[i]-i);
        return(ans);
    }
    string s1,s2,stmp;
    int main()
    {
        freopen("noip.in","r",stdin);
        freopen("noip.out","w",stdout);
        while (cin>>kk&&kk)
        {
            cin>>s1>>s2;
            string str=s1;
            memset(s,0,sizeof(s));
            strcpy(s,str.c_str());
            n=strlen(s);
            for (ll i=1;i<=n;i++)
              a[i]=s[i-1]-' ';
            ll x1,x2,x3;
            asa(n,200000);
        x1=get_ans();
            stmp=s2;
            memset(s,0,sizeof(s));
            strcpy(s,stmp.c_str());
            n=strlen(s);
            for (ll i=1;i<=n;i++)
              a[i]=s[i-1]-' ';
            asa(n,200000); x2=get_ans();
            stmp=s1+'%'+s2;
            
            memset(s,0,sizeof(s));
            strcpy(s,stmp.c_str());
            n=strlen(s);
            for (ll i=1;i<=n;i++)
              a[i]=s[i-1]-' ';
            asa(n,200000); 
        x3=get_ans();
            cout<<x3-x2-x1<<endl;
        }
        return 0;
    }
  • 相关阅读:
    谈敏捷的好文章
    梁信军说的话
    如何做需求管理
    支持向量机通俗解释
    如何写数据报告
    数据分析注意点
    傅盛谈管理的本质
    I Hate It HDU
    敌兵布阵 HDU
    P3372 【模板】线段树 1 (区间查询)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8593725.html
Copyright © 2020-2023  润新知