HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

本博客介绍了一种利用AC自动机和矩阵快速幂解决HDU 2243问题的方法,通过计算长度不超过n的非词根单词数,再从总单词数中减去这一部分来找出含有词根的单词数量。

思路:本题和POJ2778几乎是一样的,所以可以借鉴那一道题的思路。首先求出长度不超过n的不包含任何词根的单词数,然后用总的单词数减去这种情况即可。




#include<cstdio>
#include<cstring>
#include<string>
#include<cctype>
#include<iostream>
#include<set>
#include<map>
#include<cmath>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#define fin freopen("a.txt","r",stdin)
#define fout freopen("a.txt","w",stdout)
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int inf = 1e9 + 10;
const int maxnode = 35;
const int sigma_size = 26;
const int maxn = 35;
char T[maxn], s[4010];
char *p;

struct Matrix
{
    int r, c;
    ULL a[maxn][maxn];
    void init(int r, int c, ULL x) {
       this->r = r;
       this->c = c;
       for(int i = 1; i <= r; i++)
        for(int j = 1; j <= c; j++)
           a[i][j] = x;
    }

    
};

Matrix E;

Matrix operator + (const Matrix &A, const Matrix &B)
{
    int r = A.r, c = A.c;
    Matrix C; C.init(r, c, 0);
    for(int i = 1; i <= r; i++)
      for(int j = 1; j <= c; j++)
         C.a[i][j] = A.a[i][j] + B.a[i][j];
    return C;
}

Matrix operator * (const Matrix &A, const Matrix &B)
{
    int r = A.r, c = B.c;
    Matrix C; C.init(r, c, 0);
    for(int i = 1; i <= r; i++)
      for(int j = 1; j <= c; j++)
        for(int k = 1; k <= B.r; k++)
           C.a[i][j] = A.a[i][k] * B.a[k][j] + C.a[i][j];
    return C;
}

Matrix Pow(Matrix A, LL p)
{
    Matrix res = E;
    while(p)
    {
        if(p & 1) res = res * A;
        p >>= 1;
        A = A * A;
    }
    return res;
}

ULL Pow(ULL a, LL p)
{
	if(!p) return 1;
	ULL ans = Pow(a, p/2);
	ans *= ans;
	if(p & 1) ans *= a;
	return ans;
}

struct AC
{
    int ch[maxnode][sigma_size];
    int val[maxnode];
    int f[maxnode];
    int sz;
    int idx(char c) { return c - 'a'; }

    void init()
    {
        memset(ch[0], 0, sizeof ch[0]);
        sz = 1;
        memset(val,0,sizeof val);
    }

    void insert(char *s)
    {
        int n = strlen(s), u = 0;
        for(int i = 0; i < n; i++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])
            {
                memset(ch[sz], 0, sizeof ch[sz]);
                val[sz] = 0;
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
        val[u] = 1;
    }

    int getFail()
    {
    	queue<int> q;
    	f[0] = 0;
    	for(int c = 0; c < sigma_size; c++)
    	{
    		int u = ch[0][c];
    		if(u) { f[u] = 0; q.push(u); }
    	}
    	while(!q.empty())
    	{
    		int r = q.front(); q.pop();
    		for(int c = 0; c < sigma_size; c++)
    		{
    			int u = ch[r][c];
    			if(!u) { ch[r][c] = ch[f[r]][c]; continue; }
    			q.push(u);
    			int v = f[r];
    			while(v && !ch[v][c]) v = f[v];
    			f[u] = ch[v][c];
    			val[u] |= val[f[u]];
    		}
    	}
    	return 0;
    }

    Matrix getMatrix()
    {
    	Matrix A;
        A.init(sz, sz, 0);
        E.init(sz, sz, 0);
        for(int i = 1; i <= sz; i++) E.a[i][i] = 1;
        for(int i = 0; i < sz; i++)
           for(int j = 0; j < sigma_size; j++)
           {
           	   int u = i, v = ch[i][j];
           	   if(!val[v]) ++A.a[u+1][v+1];
           }
         return A;
    }

}ac;


ULL Sigma(ULL a, LL p)
{
	if(p == 0) return 1;
	if(p == 1) return a;
	LL ans = Sigma(a, p/2);
	ans = (ULL(1) + Pow(a, p/2)) * ans;
	if(p & 1) ans += Pow(a, p);
	return ans;	
}


Matrix Sigma(Matrix A, LL p)
{
	if(p == 1) return A;
	if(p == 0) return E;
	Matrix Ans = Sigma(A, p/2);
	Ans = (E + Pow(A, p/2)) * Ans;
	if(p & 1) Ans = Ans + Pow(A, p);
	return Ans;
}

int main()
{
    int n; ULL l;
    char s[100];
    while(cin >> n >> l)
    {
    	ac.init();
    	for(int i = 1; i <= n; i++)
    	{
    		scanf("%s", s);
    		ac.insert(s);
    	}
    	ac.getFail();
    	Matrix A = ac.getMatrix();
    	A = Sigma(A, l);
    	ULL ans = Sigma(26, l);
    	for(int i = 1; i <= ac.sz; i++)
    	{
    		ans -= A.a[1][i];
    	}
    	cout << ans << endl;
    }
    
	return 0;
}


跟网型逆变器小干扰稳定性分析与控制策略优化研究(Simulink仿真实现)内容概要:本文围绕跟网型逆变器的小干扰稳定性展开分析,重点研究其在电力系统中的动态响应特性及控制策略优化问题。通过构建基于Simulink的仿真模型,对逆变器在不同工况下的小信号稳定性进行建模与分析,识别系统可能存在的振荡风险,并提出相应的控制优化方法以提升系统稳定性和动态性能。研究内容涵盖数学建模、稳定性判据分析、控制器设计与参数优化,并结合仿真验证所提策略的有效性,为新能源并网系统的稳定运行提供理论支持和技术参考。; 适合人群:具备电力电子、自动控制或电力系统相关背景,熟悉Matlab/Simulink仿真工具,从事新能源并网、微电网或电力系统稳定性研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 分析跟网型逆变器在弱电网条件下的小干扰稳定性问题;② 设计并优化逆变器外环与内环控制器以提升系统阻尼特性;③ 利用Simulink搭建仿真模型验证理论分析与控制策略的有效性;④ 支持科研论文撰写、课题研究或工程项目中的稳定性评估与改进。; 阅读建议:建议读者结合文中提供的Simulink仿真模型,深入理解状态空间建模、特征值分析及控制器设计过程,重点关注控制参数变化对系统极点分布的影响,并通过动手仿真加深对小干扰稳定性机理的认识。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值