Queuing(矩阵快速幂(递推and模板))

本文介绍了一种利用矩阵快速幂的方法来解决特定队列计数问题。该问题要求找出长度为k的队列中,不包含特定模式的队列数量。通过构建特定的矩阵并使用快速幂算法进行高效计算,最终得到了问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目来源】https://vjudge.net/problem/HDU-2604
【题意】
f,m分别是female与male的缩写,假设有一个队列里面是这些字母缩写,长度为L,那么共有2^L种,如果含有fmf或者fff这种子队列的队列被称为0队列,其余的被称为E队列,问,长度为k的有多少种E队列。
【思路】
先推出前几项,得到:
f[0]=0,f[1]=2,f[2]=4,f[3]=6,f[4]=9,f[5]=15,f[6]=25;
故得到关系式:f[x]=f[x-1]+f[x-3]+f[x-4]。
其中x>=5.
所以(矩阵1)^(k-4)*矩阵2=矩阵3
我们要求矩阵3,首先要构造矩阵1和矩阵2。
那么怎么构造呢?
首先,构造矩阵1:
在f[x]=f[x-1]+f[x-3]+f[x-4]式子里:(一般递推的矩阵2都是由关系式得来的)
f[x]=f[x-1]++0*f[x-2]+f[x-3]+f[x-4]。
f[x-1]=1*f[x-1];
f[x-2]=1*f[x-2];
f[x-3]=1*f[x-3];
f[x-4]=1*f[x-4];
得到矩阵:
1 0 1 1
1 0 0 0
0 1 0 0
0 0 1 0
接着就是构造矩阵2:
f[x-1] 0 0 0
f[x-2] 0 0 0
f[x-3] 0 0 0
f[x-4] 0 0 0
……
没啦。。。质疑可以发评论讨论一下0.0 交流0.0
【代码】

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<limits.h>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int mod=9973;
typedef unsigned long long ll;
typedef long long LL;
int k,m;
struct mat
{
    int a[5][5];
    mat()
    {
        mem(a,0);
        for(int i=1; i<=4; i++)
            a[i][i]=1;
    }
};
mat operator*(mat s,mat t)
{
    mat r;
    mem(r.a,0);
    for(int i=1; i<=4; i++)
    {
        for(int j=1; j<=4; j++)
        {
            for(int p=1; p<=4; p++)
            {
                r.a[i][j]=r.a[i][j]+s.a[i][p]*t.a[p][j];
                if(r.a[i][j]>=m)
                    r.a[i][j]%=m;
            }
        }
    }
    return r;
}
void print(mat t)
{
    for(int i=1; i<=4; i++)
    {
        for(int j=1; j<=4; j++)
        {
            printf("%d ",t.a[i][j]);
        }
        printf("\n");
    }
}
mat pow_mat(mat &ans)
{
    mat base,temp;
    mem(base.a,0);
    base.a[1][1]=1;
    base.a[1][3]=1;
    base.a[1][4]=1;
    for(int i=2; i<=4; i++)
        base.a[i][i-1]=1;
    k-=4;
    while(k)
    {
        if(k&1)
            temp=temp*base;
        base=base*base;
        k>>=1;
    }
//    print(temp);
    ans=temp*ans;
}
int main()
{
    while(~scanf("%d%d",&k,&m))
    {
        if(k<5)
        {
            int p=0;
            switch(k)
            {
            case 0:
                p=0;
                break;
            case 1:
                p=2;
                break;
            case 2:
                p=4;
                break;
            case 3:
                p=6;
                break;
            case 4:
                p=9;
                break;
            }
            printf("%d\n",p%m);
        }
        else
        {
            mat ans;
            mem(ans.a,0);
            ans.a[1][1]=9;
            ans.a[2][1]=6;
            ans.a[3][1]=4;
            ans.a[4][1]=2;
            pow_mat(ans);
            printf("%d\n",(ans.a[1][1])%m);
        }
    }

}
<think>嗯,用户之前问过关于Cyclic Queuing and Forwarding(CQF)的原理,现在他们想了解编码实现或算法。我需要先回顾一下CQF的基本原理,确保自己理解正确。CQF是一种用于时间敏感网络(TSN)的技术,通过周期性的队列管理和转发来保证低延迟和确定性传输。根据引用[2],CQF利用双缓冲队列,交替进行入队和出队操作,每个周期内数据帧被转发到下一跳,这样端到端延迟由周期时间和跳数决定,不受其他流量干扰。 接下来,用户需要的是具体的实现或算法。我需要考虑如何将原理转化为实际的代码结构或算法步骤。首先,可能需要描述队列的结构,比如双缓冲队列,每个周期切换写入和读取的队列。然后,数据帧在每个周期被放入当前活动的队列,而另一个队列则被转发。这需要定时器来控制周期切换,确保所有节点同步。 然后,处理转发逻辑,当周期结束时,交换队列的读写状态,并将数据帧发送到下一跳。同时,需要考虑同步机制,比如IEEE 1588 PTP协议,来对齐不同节点的周期,避免时钟偏差导致的问题。引用[2]提到周期时间的选择和对齐是关键,否则延迟假设不成立,所以同步非常重要。 可能还需要处理边界情况,例如数据帧在周期末尾到达,是否会被延迟到下一个周期。此外,错误处理或帧丢失的情况如何处理?虽然CQF假设帧在周期内到达,但实际实现可能需要重传机制或其他容错方法,不过这可能超出了CQF的核心算法,属于扩展部分。 用户可能还想知道如何用代码表示这些队列和周期切换。比如用Python的话,可能用两个队列数组,一个定时器线程来控制周期切换,入队操作根据当前周期选择队列,出队则在周期结束时处理。需要注意线程安全和同步问题,确保在切换队列时没有数据竞争。 另外,引用[3]提到的TSN技术发展阶段可能相关,比如CQF属于TSN中的一部分,用于确保时间敏感流量的传输。可能需要结合其他TSN机制如流量整形或优先级调度来完善整个系统。 总结,我需要分步骤解释CQF的算法流程,包括队列结构、周期管理、同步机制,以及可能的代码结构示例。同时,回答相关问题时要覆盖性能分析、与类似技术的比较、工业应用等,帮助用户全面理解。</think>### Cyclic Queuing and Forwarding (CQF) 的編碼實現原理 Cyclic Queuing and Forwarding(CQF)是一种用于时间敏感网络(TSN)的流量调度算法,其核心目标是通过周期性队列管理和严格的时序控制,确保数据帧的确定性传输和固定延迟[^2][^3]。以下是其算法实现的关键原理: --- #### 1. **双缓冲队列机制** CQF的核心是使用**两个交替工作的队列**(Queue A和Queue B),每个队列对应一个固定时间周期(Cycle Time): - **周期$i$**:数据帧被写入当前活动队列(如Queue A),同时非活动队列(如Queue B)的内容被转发到下一跳。 - **周期$i+1$**:队列角色交换,Queue B变为活动队列用于写入,Queue A的内容被转发[^2]。 ```python class CQFNode: def __init__(self, cycle_time): self.queue_a = [] # 队列A self.queue_b = [] # 队列B self.current_active = 'A' # 当前活动队列 self.cycle_time = cycle_time # 周期时间(单位:毫秒) self.timer = 0 # 周期计时器 def enqueue(self, frame): if self.current_active == 'A': self.queue_a.append(frame) else: self.queue_b.append(frame) def switch_cycle(self): if self.current_active == 'A': self.current_active = 'B' frames_to_send = self.queue_a.copy() self.queue_a.clear() else: self.current_active = 'A' frames_to_send = self.queue_b.copy() self.queue_b.clear() return frames_to_send ``` --- #### 2. **周期同步与转发规则** - **全局时间同步**:所有网络节点通过协议(如IEEE 1588 PTP)严格对齐周期边界[^3]。 - **转发触发**:每个周期结束时,节点将非活动队列中的帧全部发送至下一跳。 - **端到端延迟**:总延迟为$h \times T$($h$为跳数,$T$为周期时间)[^2]。 --- #### 3. **关键参数设计** - **周期时间$T$**:需大于最大帧传输时间,且满足$T \geq \text{最大帧长} / \text{链路速率}$。 - **队列容量**:需覆盖单个周期内可能到达的帧数量,避免溢出。 - **同步精度**:节点间的时钟偏差必须远小于周期时间(如微秒级)。 --- #### 4. **实现难点与解决方案** | 难点 | 解决方案 | |------|----------| | 周期对齐 | 使用硬件时间戳和同步协议(如PTP)[^3] | | 队列切换抖动 | 硬件加速的队列管理(如FPGA实现) | | 突发流量 | 流量整形(Traffic Shaping)预处理 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值