zoukankan      html  css  js  c++  java
  • HDU

    题意:给串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
    ",ans=0);
                        continue;
                    }
                    int x=sam.go(b,b-a+1);
                    printf("%d
    ",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
    ********************/
    
  • 相关阅读:
    C++内存管理
    多线程和多进程的区别(C++)
    如何用C语言封装 C++的类,在 C里面使用
    C/C++将一个整型数组拼接成一个字符串
    C代码中如何调用C++ C++中如何调用C
    Application对象的使用-数据传递以及内存泄漏
    《鸟哥的Linux私房菜》读书笔记二
    《鸟哥的Linux私房菜》读书笔记一
    greenDaoMaster的学习研究
    Handler 引起的内存泄露
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10767973.html
Copyright © 2011-2022 走看看