zoukankan      html  css  js  c++  java
  • Wannafly Camp 2020 Day 2K 破忒头的匿名信

    给定字典和文章,每个单词有价值,求写文章的最小价值

    标准的 AC 自动机 dp,设 (f[i]) 表示写 (s[1..i]) 的最小价值,建立AC自动机后根据 trans 边暴力转移即可

    建了个中间图结果被卡内存了,被迫删掉

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 5e5+5;
    vector <pair<signed,signed> > g[N];
    int slen[N],w[N],ttt;
    int min(signed x,int y) {return min(1ll*x,y);}
    int f[N];
    void msgOccur(int len,int pos,int wei) {
        ++pos; ++ttt;
        int p = pos-len;
        //f[i]=min(f[i],f[g[i][j].first]+g[i][j].second);
        //g[pos].push_back(make_pair(p,wei));
        f[pos]=min(f[pos],f[p]+wei);
    }
    struct ACA{
    	signed c[N][26],val[N],fi[N],cnt,ans[N];
    	void init(){
    		memset(c,0,sizeof c); memset(val,0x3f,sizeof val);
    		memset(fi,0,sizeof fi); memset(ans,0,sizeof ans); cnt=0;}
    	void ins(char *str,int id){
    		int len=strlen(str), p=0;
    		for(int i=0;i<len;i++){
    			int v=str[i]-'a';
    			if(!c[p][v]) c[p][v]=++cnt;
    			p=c[p][v];}
    		val[p]=min(val[p],w[id]);
    		slen[p]=len;}
    	void build(){
    	    queue <signed> q;
    		for(int i=0;i<26;i++) if(c[0][i]) fi[c[0][i]]=0, q.push(c[0][i]);
    		while(!q.empty()){
    			int u=q.front(); q.pop();
    			for(int i=0;i<26;i++)
    				if(c[u][i]) fi[c[u][i]]=c[fi[u]][i], q.push(c[u][i]);
    				else c[u][i]=c[fi[u]][i];}}
    	int query(char *s){
    		int len=strlen(s); int p=0;
    		for(int i=0;i<len;i++){
    			p=c[p][s[i]-'a'];
    			for(int t=p;t&&~val[t];t=fi[t])
    				msgOccur(slen[t],i,val[t]);}}
    } AC;
    int n; char p[N]; string mp[N];
    
    signed main(){
    	scanf("%lld",&n);
        memset(p,0,sizeof p); AC.init();
        for(int i=1;i<=n;i++) {
            scanf("%s%lld",p,&w[i]);
            AC.ins(p,i);
            mp[i]=p;
            //slen[i]=strlen(p);
        }
        AC.build();
        scanf("%s",p);
        memset(f,0x3f,sizeof f);
        f[0]=0;
        int ans=AC.query(p);
        int len=strlen(p);
        cout<<(f[len]>=len*1000000000?-1:f[len])<<endl;
    }
    
  • 相关阅读:
    JAVA之代理2CGLib
    Java并发编程:Lock
    synchronized详解
    redis哨兵机制--配置文件sentinel.conf详解
    redis.conf讲解
    [Java并发包学习八]深度剖析ConcurrentHashMap
    [Java并发包学习七]解密ThreadLocal
    T和Class以及Class的理解
    python学习笔记十:异常
    python学习笔记九:正则表达式
  • 原文地址:https://www.cnblogs.com/mollnn/p/12323612.html
Copyright © 2011-2022 走看看