HDU - 6054String and String

时间:2023-03-08 15:50:13
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
********************/