2017年8月10日(回归训练第一天)ac自动机&&整体二分

来源:互联网 发布:泉州市网络推手 编辑:程序博客网 时间:2024/05/17 17:57
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]);} elsenext[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;}


原创粉丝点击