• 新疆省赛A.A. chino with string(AC自动机+广义矩阵快速幂)


    前置知识:

    [TJOI2012]可乐

    广义矩阵快速幂

    AC自动机

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    typedef long long ll;
    int nxt[maxn][26],fail[maxn];
    ll c[maxn];
    int tot=1,rt=1,n,m;
    void ins (string s,int x) {
    	int u=rt;
    	for (char i:s) {
    		if (!nxt[u][i-'a']) nxt[u][i-'a']=++tot;
    		u=nxt[u][i-'a'];
    	}
    	c[u]+=x;
    }
    void build () {
    	queue<int> q;
    	fail[rt]=rt;
    	for (int i=0;i<26;i++) {
    		if (!nxt[rt][i]) nxt[rt][i]=rt;
    		else {
    			fail[nxt[rt][i]]=rt;
    			q.push(nxt[rt][i]);
    		}
    	}
    	while (q.size()) {
    		int u=q.front();
    		q.pop();
    		for (int i=0;i<26;i++) {
    			if (!nxt[u][i]) {
    				nxt[u][i]=nxt[fail[u]][i];
    			}
    			else {
    				fail[nxt[u][i]]=nxt[fail[u]][i];
    				q.push(nxt[u][i]);
    			}
    		}
    	}
    }
    vector<int> g[maxn];
    ll cc[maxn];
    void dfs (int u,ll sum) {
    	cc[u]=sum;
    	for (int v:g[u]) {
    		dfs(v,sum+c[v]);
    	}
    }
    struct matrix {
    	ll m[205][205];
    }ans,base;
    matrix mul (matrix a,matrix b) {
    	matrix ans;
    	for (int i=1;i<=tot;i++) for (int j=1;j<=tot;j++) ans.m[i][j]=-1e18;
    //	for (int i=1;i<=tot;i++) for (int j=1;j<=tot;j++) {
    //		ans.m[i][j]=max(a.m[i][j],b.m[i][j]);
    //	}
    	for (int k=1;k<=tot;k++) {
    		for (int i=1;i<=tot;i++) {
    			for (int j=1;j<=tot;j++) {
    				if (a.m[i][k]!=-1e18&&b.m[k][j]!=-1e18)
    					ans.m[i][j]=max(ans.m[i][j],a.m[i][k]+b.m[k][j]);
    			}
    		}
    	}
    	return ans; 
    }
    void qpow (int p) {
    	while (p) {
    		if (p&1) ans=mul(ans,base);
    		base=mul(base,base);
    		p>>=1;
    	} 
    }
    
    /*
    17 3
    helloworld 100
    ldldl 5
    aaa -6
    */
    int main () {
    	cin>>n>>m;
    	for (int i=1;i<=m;i++) {
    		string s;
    		int x;
    		cin>>s>>x;
    		ins(s,x);
    	}
    	build();
    	for (int i=2;i<=tot;i++) g[fail[i]].push_back(i);
    	dfs(1,c[1]);
    	//for (int i=1;i<=tot;i++) printf("%d ",cc[i]);
    	//puts("");
    	for (int i=1;i<=tot;i++) for (int j=1;j<=tot;j++) {
    		base.m[i][j]=-1e18;
    	}
    	for (int i=1;i<=tot;i++) {
    		for (int j=0;j<26;j++) {
    			base.m[i][nxt[i][j]]=cc[nxt[i][j]];
    		}
    	}
    	ans=base;
    //	for (int i=1;i<=tot;i++) {
    //		for (int j=1;j<=tot;j++) printf("%lld ",base.m[i][j]);
    //		puts("");
    //	}
    	//n=1;
    	//n=17;
    	qpow(n-1);
    	long long Ans=-1e18;
    	for (int i=1;i<=tot;i++) {
    		Ans=max(Ans,ans.m[1][i]);
    		//printf("%lld ",ans.m[1][i]);
    	}
    	printf("%lld
    ",Ans);
    }
  • 相关阅读:
    磁盘挂载基本概念
    判断cache Line的作用
    map的用法
    java中关键字volatile的作用
    Java获取用户输入
    小白说编译原理lex和yacc环境配置-多图
    C++中对sprintf()函数的说明(转)
    解决VS编译DevExpress后Debug默认产生几个多余的语言包"de" "en" "es" "ja" "ru"的问题
    SqlServer发现不是默认端口1433该如何进行连接
    量化交易之接口篇 — 恒生UFX交易接口基本介绍说明
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15195249.html
Copyright © 2020-2023  润新知