SPOJ 8222 NSUBSTR Substrings


SAM的简单应用....

由SAM可知从root到达的每个节点所经过的路径都对着应原串的一个子串,每个节点能到几次接收态就等于这个子串出现了几次。从最后一个节点往上走,就可以用DP更新出每个子串出现了多少次。

出现了5次的子串一定也出现了4,3,2,1次。。。所以最后再用长度长的给长度小的更新一下。。。。

Time Limit: 1000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

[]   [Go Back]   [Status]  

Description

You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string 'ababa' F(3) will be 2 because there is a string 'aba' that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.

Input

String S consists of at most 250000 lowercase latin letters.

Output

Output |S| lines. On the i-th line output F(i).

Example

Input:
ababa

Output:
3
2
2
1
1

Source

Immagination

[]   [Go Back]   [Status]  


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn=600000;

struct SAM_Node
{
    SAM_Node *fa,*next[26];
    int len,id,pos;
    SAM_Node(){}
    SAM_Node(int _len)
    {
        len=_len; fa=0;
        memset(next,0,sizeof(next));
    }
};

SAM_Node SAM_node[maxn*2],*SAM_root,*SAM_last;
int SAM_size;

SAM_Node *newSAM_Node(int len)
{
    SAM_node[SAM_size]=SAM_Node(len);
    SAM_node[SAM_size].id=SAM_size;
    return &SAM_node[SAM_size++];
}

SAM_Node *newSAM_Node(SAM_Node *p)
{
    SAM_node[SAM_size]=*p;
    SAM_node[SAM_size].id=SAM_size;
    return &SAM_node[SAM_size++];
}

void SAM_init()
{
    SAM_size=0;
    SAM_root=SAM_last=newSAM_Node(0);
    SAM_node[0].pos=0;
}

void SAM_add(int x,int len)
{
    SAM_Node *p=SAM_last,*np=newSAM_Node(p->len+1);
    np->pos=len; SAM_last=np;
    for(;p&&!p->next[x];p=p->fa)
        p->next[x]=np;
    if(!p)
    {
        np->fa=SAM_root;
        return ;
    }
    SAM_Node *q=p->next[x];
    if(q->len==p->len+1)
    {
        np->fa=q;
        return ;
    }
    SAM_Node *nq=newSAM_Node(q);
    nq->len=p->len+1;
    q->fa=nq; np->fa=nq;
    for(;p&&p->next[x]==q;p=p->fa)
        p->next[x]=nq;
}

char str[maxn];
bool vis[maxn];
int r[maxn],dp[maxn];

int Find(SAM_Node *p)
{
    if(vis[p->id]==true)
        return r[p->id];
    vis[p->id]=true;
    r[p->id]=0;
    for(int i=0;i<26;i++)
    {
        if(p->next[i])
            r[p->id]+=Find(p->next[i]);
    }
    return r[p->id];
}

void get_count()
{
    memset(r,0,sizeof(r));
    memset(vis,0,sizeof(vis));
    SAM_Node *p=SAM_last;
    vis[p->id]=true;
    for(;p;p=p->fa)
    {
        Find(p);
        r[p->id]++;
    }
}

int main()
{
while(scanf("%s",str)!=EOF)
{
    int n=strlen(str);
    SAM_init();
    for(int i=0;i<n;i++)
        SAM_add(str[i]-'a',i+1);
    get_count();
    memset(dp,0,sizeof(dp));
    for(int i=0;i<SAM_size;i++)
    {
        dp[SAM_node[i].len]=max(dp[SAM_node[i].len],r[SAM_node[i].id]);
    }
    for(int i=n-1;i>=1;i--)
    {
        dp[i]=max(dp[i],dp[i+1]);
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",dp[i]);
    }
}
    return 0;
}




### 如何计算神经网络参数量FLOPs #### 参数量 (Params) 参数量指的是模型中可训练参数的数量总和。对于卷积层而言,其参数数量可以通过下面的方式得出: \[ \text{params} = (\text{kernel height} * \text{kernel width} * \text{input channels} + 1) * \text{output channels} \] 其中,“+1”代表偏置项(bias),如果该层不使用偏置,则无需加上这一部分。 对于全连接层来说,参数数目等于输入节点数乘以输出节点数再加上一个偏置向量[^4]。 为了统计整个网络中的参数总量,在Python环境下可以利用PyTorch框架提供的接口遍历所有层并累加各层参数: ```python total_params = sum(p.numel() for p in model.parameters()) print(f&#39;Total number of parameters: {total_params}&#39;) ``` 这段代码会返回给定`model`对象内所有的可训练参数之和[^5]。 #### 浮点运算次数 (FLOPs) 浮点操作数(Floating Point Operations Per Second, FLOPs),用于描述执行一次前向传播过程中涉及了多少次基本数学运算(比如加法、减法、乘法)。它不仅取决于权重矩阵尺寸还关联到激活函数的选择等因素。 针对不同类型的层有不同的估算方式;例如标准二维卷积层的理论FLOPs可通过如下公式近似估计: \[ \text{FLOPs}_{conv2d} = 2 * W_{out}H_{out}\times C_{in}\times K_hK_w\times C_{out}/S^2 \] 这里\(W_{out}, H_{out}\)表示输出特征图宽高,\(C_{in}, C_{out}\)分别是输入输出通道数,\(K_h,K_w\)为核大小而\(S\)则是步幅(step size)[^3]。 实际应用中推荐借助第三方库如`thop`来自动化获取更精确的结果: ```python from thop import profile macs, params = profile(model, inputs=(input_tensor,)) print(&#39;Computational complexity:&#39;, macs) print(&#39;Number of parameters:&#39;, params) ``` 上述脚本能够方便快捷地得到指定模型及其输入张量组合下的MACs(Multiply-Accumulate operations)与参数计数[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值