AC自动机:
#include <stdio.h>
#include <cstring>
#include <queue>
using namespace std;
const int N=26;
const int maxN=50005;
struct Trie{
int fail[maxN],next[maxN][N],end[maxN];
int root,tot;
int new_node()
{
for (int i=0; i<N; i++)
next[tot][i]=-1;
end[tot++]=0;
return tot-1;
}
void init()
{
tot=0;
root=new_node();
}
void insert(char buf[])
{
int len=strlen(buf);
int now=root;
for (int i=0; i<len; i++)
{
int k=buf[i]-'a';
if (next[now][k]==-1) next[now][k]=new_node();
now=next[now][k];
}
end[now]++;
}
void build()
{
queue <int> p;
fail[root]=root;
for (int i=0; i<N; i++)
{
if (next[root][i]==-1) next[root][i]=root;
else
{
fail[next[root][i]]=root;
p.push(next[root][i]);
}
}
while (!p.empty())
{
int now=p.front();
p.pop();
for (int i=0; i<N; i++)
{
if (next[now][i]!=-1)
{
fail[next[now][i]]=next[fail[now]][i];
p.push(next[now][i]);
} else
next[now][i]=next[fail[now]][i];
}
}
}
int query(char buf[])
{
int len=strlen(buf);
int now=root;
int ans=0;
for (int i=0; i<len; i++)
{
now=next[now][buf[i]-'a'];
int temp=now;
while (temp!=root)
{
ans+=end[temp];
end[temp]=0;
temp=fail[temp];
}
}
return ans;
}
}ac;
char buf[maxN+maxN];
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n;
scanf("%d",&n);
ac.init();
for (int i=1; i<=n; i++)
{
scanf("%s",&buf);
ac.insert(buf);
}
ac.build();
scanf("%s",&buf);
printf("%d\n",ac.query(buf));
}
return 0;
}
整体二分:
#include <stdio.h>
#include <vector>
#include <cstring>
using namespace std;
const int maxN=300010;
struct Tnode{
int l,r,c;
}p[maxN];
vector <int> e[maxN];
long long tree[maxN];
struct Tpoint{
long long x;
int y;
}a[maxN],b[maxN];
long long ans[maxN];
int n,m,k;
int add(int pos,int x)
{
for (int i=pos; i<=m; i+=i&(-i)) tree[i]+=(long long)x;
}
int query(int pos)
{
long long ret=0;
for (int i=pos; i>0; i-=i&(-i)) ret+=tree[i];
return ret;
}
void solve (int l,int r,int L,int R)
{
if (l>r || L>R) return ;
int mid=(l+r)/2;
for (int i=l; i<=mid; i++)
{
// printf("p[%d] l:%d r:%d c:%d\n",i,p[i].l,p[i].r,p[i].c);
if (p[i].l<=p[i].r) add(p[i].l,p[i].c),add(p[i].r+1,-p[i].c);
else add(1,p[i].c),add(p[i].r+1,-p[i].c),add(p[i].l,p[i].c);
}
int t1=L,t2=R;
// printf( "%d ",mid);
for (int i=L; i<=R; i++)
{
int now=a[i].y;
int len=e[now].size();
long long sum=0;
for (int j=0; j<len; j++) sum+=query(e[now][j]);
if (sum>=a[i].x)
{
ans[now]=mid;
b[t1++]=a[i];
}
else
{
a[i].x-=sum;
b[t2--]=a[i];
}
}
for (int i=L; i<=R; i++) a[i]=b[i];
for (int i=l; i<=mid; i++)
{
if (p[i].l<=p[i].r) add(p[i].l,-p[i].c),add(p[i].r+1,p[i].c);
else add(1,-p[i].c),add(p[i].r+1,p[i].c),add(p[i].l,-p[i].c);
}
if (t2!=R || r!=mid) solve(l,mid,L,t2);
if (t1!=L || mid+1!=l) solve(mid+1,r,t1,R);
}
int main()
{
freopen("2202.in","r",stdin);
freopen("2202.out","w",stdout);
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&n,&m);
memset(e,0,sizeof e);
memset(tree,0,sizeof tree);
memset(ans,0,sizeof ans);
for (int i=1; i<=m; i++)
{
int x;
scanf("%d",&x);
e[x].push_back(i);
}
for (int i=1; i<=n; i++)
{
scanf("%d",&a[i].x);
a[i].y=i;
}
scanf("%d",&k);
for (int i=1; i<=k; i++) scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].c);
solve(1,k,1,n);
for (int i=1; i<=n; i++)
{
if (ans[i]==0) printf("-1\n");
else printf("%lld\n",ans[i]);
}
}
return 0;
}
2017年8月10日(回归训练第一天)ac自动机&&整体二分
最新推荐文章于 2024-03-15 14:10:50 发布