按道理来说应该没有问题,分块+AC自动机,竟然WA了。求助dalao
#include <bits/stdc++.h>
using namespace std;
long long n,m,k,op,trie[300000][3],a[300000],ap[300000],fail[300000],add[1000],cov[1000],id[300000],d[300000],cnt=0,ans=0;
string s[300000];
bool trgr[300000][3];
vector<int>ft[300000];
//First Part:Piecemeal
void update()
{
long long l,r,w;
cin>>l>>r>>w;
long long p=id[l],q=id[r];
if(p==q)
for(long long i=l;i<=r;i++)a[i]+=w;
else
{
for(long long i=l;i<=p*k;i++)a[i]+=w;
for(long long i=(q-1)*k+1;i<=r;i++)a[i]+=w;
for(long long i=p+1;i<=q-1;i++)add[i]+=w;
}
}
void under(long long p)
{
if(cov[p])
{
for(long long i=(p-1)*k+1;i<=p*k;i++)a[i]=cov[p]+add[p];
cov[p]=0;add[p]=0;
}
}
long long query(long long i)
{
if(cov[id[i]])return cov[id[i]]+add[id[i]];
else return a[i]+add[id[i]];
}
void cover()
{
long long l,r,w;
cin>>l>>r>>w;
long long p=id[l],q=id[r];
if(p==q)
{
under(p);
for(long long i=l;i<=r;i++)a[i]=w;
}
else
{
under(p);
for(long long i=l;i<=p*k;i++)a[i]=w;
under(q);
for(long long i=(q-1)*k+1;i<=r;i++)a[i]=w;
for(long long i=p+1;i<=q-1;i++)cov[i]=w,add[i]=0;
}
}
//Second Part:AC Automation
long long insert(string str)
{
long long l=str.size(),root=0;
for(long long i=0;i<l;i++)
{
long long id=str[i]-'a';
if(!trie[root][id])trie[root][id]=++cnt;
root=trie[root][id];
}
return root;
}
void build_ac()
{
long long h=1,t=0,que[300000];
for(long long i=0;i<3;i++)
if(trie[0][i])que[++t]=trie[0][i];
while(h<=t)
{
long long now=que[h];
for(long long i=0;i<3;i++)
if(trie[now][i])fail[trie[now][i]]=trie[fail[now]][i],que[++t]=trie[now][i];
else trie[now][i]=trie[fail[now]][i],trgr[now][i]=1;
h++;
}
}
void build_ft()
{
for(long long root=0;root<=cnt;root++)
for(long long i=0;i<3;i++)
if(trie[root][i]&&!trgr[root][i])ft[fail[trie[root][i]]].push_back(trie[root][i]);
}
long long tree_dp(long long root,long long l,long long r)
{
long long cnt=0,len=ft[root].size();
cnt+=ap[root];
for(long long i=0;i<len;i++)
cnt+=tree_dp(ft[root][i],l,r);
if(d[root]>=l&&d[root]<=r)ans+=query(d[root])*cnt;
return cnt;
}
void match_ac()
{
long long l,r,len,root=0;
string str;
cin>>l>>r>>str;
len=str.size();
for(long long i=0;i<len;i++)
root=trie[root][str[i]-'a'],ap[root]++;
tree_dp(0,l,r);
cout<<ans<<endl;
root=0;
for(long long i=0;i<len;i++)
root=trie[root][str[i]-'a'],ap[root]=0;
ans=0;
}
int main()
{
cin>>n>>m;
k=sqrt(n);
for(long long i=1;i<=n;i++)
{
cin>>s[i]>>a[i];
id[i]=(i-1)/k+1;
d[insert(s[i])]=i;
}
build_ac();
build_ft();
for(long long i=1;i<=m;i++)
{
cin>>op;
if(op==1)update();
else if(op==2)cover();
else match_ac();
}
return 0;
}