HDU - 6054String and String

题意:给串s和t,对于串s每个位置有一个价值f,两种操作1.修改f[a]=b,2.查询串t子串Ta-b在s的子串Sc-d中出现位置的f和
题解:s和t建sam,把fail树按dfs序建bit套线段树,就变成了单点修改,子树(区间)查询区间个数

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
//#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define ull unsigned long long
//#define base 1000000000000000000
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}

using namespace std;

const ull ba=233;
const db eps=1e-5;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=200000+10,maxn=1000000+10,inf=0x3f3f3f3f;

int NX,n;
struct bit_seg{
    int root[N<<1],ls[N*100],rs[N*100],sum[N*100],res;
    void init()
    {
        for(int i=0;i<=NX;i++)root[i]=0;
        for(int i=0;i<=res;i++)ls[i]=rs[i]=sum[i]=0;
        res=0;
    }
    void update(int &o,int pos,int v,int l,int r)
    {
        if(!o)o=++res;
        sum[o]+=v;
        if(l==r)return ;
        int m=(l+r)>>1;
        if(pos<=m)update(ls[o],pos,v,l,m);
        else update(rs[o],pos,v,m+1,r);
    }
    int query(int L,int R,int o,int l,int r)
    {
        if(!o||l>r||L>R)return 0;
        if(L<=l&&r<=R)return sum[o];
        int m=(l+r)>>1,ans=0;
        if(L<=m)ans+=query(L,R,ls[o],l,m);
        if(m<R)ans+=query(L,R,rs[o],m+1,r);
        return ans;
    }
    int bitquery(int L,int R,int a,int b)
    {
        int ans=0;
        for(int i=R;i;i-=i&(-i))ans+=query(a,b,root[i],0,n-1);
        for(int i=L-1;i;i-=i&(-i))ans-=query(a,b,root[i],0,n-1);
        return ans;
    }
    void bitupdate(int i,int pos,int v)
    {
        for(;i<=NX;i+=i&(-i))update(root[i],pos,v,0,n-1);
    }
}bs;
char s[N],p[N];
int pos[N][2];
int g[N];
struct SAM{
    int last,cnt;
    int ch[N<<1][26],fa[N<<1],l[N<<1];
    int f[N<<1][20],L[N<<1],R[N<<1],res;
    struct edge{int to,Next;}e[N<<1];
    int head[N<<1],cnt1;
    void add(int u,int v){e[cnt1].to=v,e[cnt1].Next=head[u];head[u]=cnt1++;}
    void init(){
        for(int i=1;i<=cnt;i++)
        {
            memset(ch[i],0,sizeof ch[i]);
            l[i]=fa[i]=L[i]=R[i]=0;
        }
        memset(head,-1,sizeof head);
        cnt=1;
        res=cnt1=0;
    }
    void ins(int c){
        if(ch[last][c])
        {
            int p=last,q=ch[last][c];
            if(l[q]==l[p]+1)last=q;
            else
            {
                int nq=++cnt;l[nq]=l[p]+1;
                memcpy(ch[nq],ch[q],sizeof ch[q]);
                fa[nq]=fa[q];fa[q]=last=nq;
                for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            }
            return ;
        }
        int p=last,np=++cnt;last=np;l[np]=l[p]+1;
        for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
        if(!p)fa[np]=1;
        else
        {
            int q=ch[p][c];
            if(l[p]+1==l[q])fa[np]=q;
            else
            {
                int nq=++cnt;l[nq]=l[p]+1;
                memcpy(ch[nq],ch[q],sizeof(ch[q]));
                fa[nq]=fa[q];fa[q]=fa[np]=nq;
                for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            }
        }
    }
    int go(int x,int y)
    {
        x=pos[x][1];
        for(int i=19;~i;--i)if(l[f[x][i]]>=y)x=f[x][i];
        return x;
    }
    void dfs(int u)
    {
        L[u]=++res;
        for(int i=head[u];~i;i=e[i].Next)dfs(e[i].to);
        R[u]=res;
    }
    void gao()
    {
        last=1;
        int lens=strlen(s),lenp=strlen(p);
        for(int i=0;i<lens;i++)ins(s[i]-'a'),pos[i][0]=last;
        last=1;
        for(int i=0;i<lenp;i++)ins(p[i]-'a'),pos[i][1]=last;
        NX=cnt;n=lens;
        for(int i=1;i<=cnt;i++)
        {
            f[i][0]=fa[i];
            if(fa[i])add(fa[i],i);
        }
        dfs(1);
        for(int i=0;i<lens;i++)scanf("%d",&g[i]), bs.bitupdate(L[pos[i][0]],i,g[i]);
        for(int i=1;i<=19;i++)
            for(int j=1;j<=cnt;j++)
                f[j][i]=f[f[j][i-1]][i-1];
    }
}sam;
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        sam.init();
        bs.init();
        scanf("%s%s",s,p);
        sam.gao();
        int q,ans=0;scanf("%d",&q);
        while(q--)
        {
            int op,a,b,c,d;scanf("%d%d%d",&op,&a,&b);
            a^=ans,b^=ans;
            if(op==1)
            {
                bs.bitupdate(sam.L[pos[a][0]],a,b-g[a]);
                g[a]=b;
            }
            else
            {
                scanf("%d%d",&c,&d);c^=ans,d^=ans;
                c+=b-a;
                if(c>d)
                {
                    printf("%d\n",ans=0);
                    continue;
                }
                int x=sam.go(b,b-a+1);
                printf("%d\n",ans=bs.bitquery(sam.L[x],sam.R[x],c,d));
            }
        }
    }
    return 0;
}
/********************
1
abab
baba
6 1 2 3
3
2 0 1 0 3
1 6 6
2 6 6 6 4
********************/
posted @ 2019-04-25 13:44  walfy  阅读(189)  评论(0编辑  收藏  举报