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;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/8593725.html