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
    ********************/
    
  • 相关阅读:
    CodeForces 681D Gifts by the List (树上DFS)
    UVa 12342 Tax Calculator (水题,纳税)
    CodeForces 681C Heap Operations (模拟题,优先队列)
    CodeForces 682C Alyona and the Tree (树上DFS)
    CodeForces 682B Alyona and Mex (题意水题)
    CodeForces 682A Alyona and Numbers (水题,数学)
    Virtualizing memory type
    页面跳转
    PHP Misc. 函数
    PHP 5 Math 函数
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10767973.html
Copyright © 2011-2022 走看看