zoukankan      html  css  js  c++  java
  • 【LGP5161】WD与数列

    题目

    也是可以用(SAM)来做的

    我们发现要求原串不相交,那么就要求在差分序列里不相交并且不相邻

    考虑一下(SAM),暴力做法自然是对每一个节点统计其所有(endpos)的影响

    既然这样我们为什么不直接启发式合并加线段树合并分类讨论一下呢

    于是可休闲了

    我们考虑往一个节点里插入一个新的(endpos)会产生什么影响

    1. 对于那些(x-endpos>=mxlen+1)(x),我们这样插入显然是会产生(x)的贡献

    2. 如果(x-endpos<mxlen+1),那么就会产生(|x-enspos|-1)的贡献

    分情况讨论一下这些贡献就好了

    于是同时维护动态开点线段树就好了,合并直接线段树合并

    代码

    #include<tr1/unordered_map>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register
    #define LL long long
    #pragma GCC optimize(3)
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("Ofast,no-stack-protector")
    const int maxn=6e5+5;
    const int R=2e5+5;
    const int M=2.2e7;
    using namespace std::tr1;
    inline int read() {
        char c=getchar();int x=0,r=1;
        while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return r*x;
    }
    int n,cnt=1,lst=1,tot,tax[maxn>>1],A[maxn];
    unordered_map<int,int> son[maxn];
    int len[maxn],fa[maxn];
    std::vector<int> pos[maxn];
    int a[maxn>>1];
    int rt[maxn],l[M],r[M],t[M];
    int st[maxn>>1],top;
    LL d[M],ans,D,T;
    int change(int now,int x,int y,int pos) {
        if(!now) {
            if(!top) now=++tot;
            else now=st[top--];
        }
        t[now]++,d[now]+=pos;
        if(x==y) return now;
        int mid=x+y>>1;
        if(pos<=mid) l[now]=change(l[now],x,mid,pos);
            else r[now]=change(r[now],mid+1,y,pos);
        return now;
    }
    LL ask(int now,int x,int y,int lx,int ry) {
        if(!now||x>y) return 0;
        if(x<=lx&&y>=ry) return t[now];
        int mid=lx+ry>>1;
        if(y<=mid) return ask(l[now],x,y,lx,mid);
        if(x>mid) return ask(r[now],x,y,mid+1,ry);
        return ask(l[now],x,y,lx,mid)+ask(r[now],x,y,mid+1,ry);
    }
    void query(int now,int x,int y,int lx,int ry) {
        if(!now||x>y) return;
        if(x<=lx&&y>=ry) {T+=t[now],D+=d[now];return;}
        int mid=lx+ry>>1;
        if(x<=mid) query(l[now],x,y,lx,mid);
        if(y>=mid+1) query(r[now],x,y,mid+1,ry);
    }
    inline void ins(int c,int k) {
        int p=++cnt,f=lst;lst=p;
        len[p]=len[f]+1;
        pos[p].push_back(k);rt[p]=change(rt[p],1,n-1,k);
        while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
        if(!f) {fa[p]=1;return;}
        int x=son[f][c];
        if(len[f]+1==len[x]) {fa[p]=x;return;}
        int y=++cnt;len[y]=len[f]+1;
        fa[y]=fa[x],fa[x]=fa[p]=y;son[y]=son[x];
        while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
    }
    int merge(int a,int b,int x,int y) {
    	if(!a||!b) return a+b;
    	if(x==y) {t[a]+=t[b];d[a]+=d[b];}
    	int mid=x+y>>1;
    	l[a]=merge(l[a],l[b],x,mid);r[a]=merge(r[a],r[b],mid+1,y);
    	t[a]=t[l[a]]+t[r[a]],d[a]=d[l[a]]+d[r[a]];
    	return a;
    }
    int main() {
        n=read();
        for(re int i=1;i<=n;++i) a[i]=read();
        for(re int i=1;i<n;++i) ins(a[i+1]-a[i],i);
        for(re int i=1;i<=cnt;++i) tax[len[i]]++;
        for(re int i=1;i<n;i++) tax[i]+=tax[i-1];
        for(re int i=cnt;i>=0;--i) A[tax[len[i]]--]=i;
        for(re int i=cnt;i;--i) {
            int x=A[i],F=fa[x];
            if(pos[x].size()>pos[F].size()) std::swap(pos[x],pos[F]),std::swap(rt[x],rt[F]);
            for(re int j=0;j<pos[x].size();j++) {
                int now=pos[x][j];
                ans+=ask(rt[F],now+1+len[F],n-1,1,n-1)*(LL)len[F];
                ans+=ask(rt[F],1,now-len[F]-1,1,n-1)*(LL)len[F];
                
                T=D=0;query(rt[F],now-len[F],now-1,1,n-1);
                ans+=T*((LL)now-1)-D;
                
                T=D=0;query(rt[F],now+1,now+len[F],1,n-1);
                ans+=D-T*((LL)now+1);
                
                pos[F].push_back(now);
            }
            rt[F]=merge(rt[F],rt[x],1,n-1);
        }
        ans+=(LL)(n-1)*n/2ll;
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    VS2010快捷键
    mvc 简单的分页扩展
    Asp.net(C#)给图片加上水印效果
    HTML特殊字符编码大全
    获取URL上的参数值
    json数据的时间格式转换如:/Date(2342561534)/
    js中文编码到C#后台解码
    获取浏览器滚动条高度
    使用js画图
    silverlight实时从Javascript获取json数据
  • 原文地址:https://www.cnblogs.com/asuldb/p/10557181.html
Copyright © 2011-2022 走看看