SPOJ DISUBSTR Distinct Substrings

本文介绍了一种利用DC3算法解决寻找给定字符串中所有不重复子串数量的方法。通过输入字符串,该算法可以高效地计算出所有可能的不同子串数目。

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

Description
Given a string, we need to find the total number of its distinct substrings.

Input

T- number of test cases. T<=20;
Each test case consists of one string, whose length is <= 1000

Output

For each test case output one number saying the number of distinct substrings.

Example

Sample Input:
2
CCCCC
ABABA

Sample Output:
5
9

Explanation for the testcase with string ABABA:
len=1 : A,B
len=2 : AB,BA
len=3 : ABA,BAB
len=4 : ABAB,BABA
len=5 : ABABA
Thus, total number of distinct substrings is 9.

题意:求不重复的子串有多少个
思路 : 对于一个以第k个字符为起始位置的字符串 ,他能产生的前缀为len - k 个,但是有height[rank[k]] 个是重复的,所以要减去。这道题我使用DC3 写的,

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>

using namespace std;
#define MAXN 1010*3
#define F(x) ((x)/3 + ((x)%3 == 1 ? 0 : tb))
#define G(x) ((x) < tb?(x)*3 + 1:((x) - tb)*3+2)
int wa[MAXN], wb[MAXN], wv[MAXN], wss[MAXN];
int c0(int *r, int a, int b)
{
    return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2];
}
int c12(int k, int *r, int a, int b)
{
    if(k == 2)
        return r[a] < r[b] || (r[a] == r[b] && c12(1, r, a + 1, b + 1));
      else return r[a] < r[b] || (r[a] == r[b] && wv[a + 1] < wv[b + 1]);
}
void _sort(int *r, int *a, int *b, int n, int m)
{
    int i;
    for( i = 0; i < n; i++) wv[i] = r[a[i]];
    for( i = 0; i < m; i++) wss[i] = 0;
    for( i = 0; i < n; i++) wss[wv[i]]++;
    for( i = 1; i < m; i++) wss[i] += wss[i - 1];
    for( i = n - 1; i >= 0; i--) b[--wss[wv[i]]] = a[i];
}
void dc3(int *r, int *sa, int n, int m)
{
    int i, j, *rn = r + n;
    int *san = sa + n, ta = 0, tb = (n + 1)/3, tbc = 0, p;
    r[n] = r[n+1] = 0;
    for( i = 0; i < n; i++) if(i%3 != 0) wa[tbc++] = i;
    _sort(r + 2, wa, wb, tbc, m);
    _sort(r + 1, wb, wa, tbc, m);
    _sort(r, wa, wb, tbc, m);
    for( p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++)
     rn[F(wb[i])] = c0(r, wb[i - 1], wb[i])? p - 1 : p ++;
    if(p < tbc) dc3(rn, san, tbc, p);
    else for( i = 0; i < tbc; i++) san[rn[i]] = i;
    for( i = 0; i < tbc; i++)
        if(san[i] < tb) wb[ta++] = san[i] * 3;
    if(n % 3 == 1) wb[ta++] = n - 1;
    _sort(r, wb, wa, ta, m);
    for( i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i;
    for( i = 0, j = 0, p = 0; i < ta && j < tbc; p ++)
        sa[p] = c12(wb[j]%3, r, wa[i], wb[j]) ? wa[i++]: wb[j++];
    for( ; i < ta; p++) sa[p] = wa[i++];
    for( ; j < tbc; p++) sa[p] = wb[j ++];
}

void da(int str[], int sa[], int _rank[], int height[], int n, int m)
{
    for( int i = n; i < n*3; i++)
        str[i] = 0;
    dc3(str, sa, n + 1, m);
    int i, j, k = 0;
    for( i = 0; i <= n; i++) _rank[sa[i]] = i;
    for( i = 0; i < n; i++)
    {
        if(k) k --;
        j = sa[_rank[i] - 1];
        while(str[i+k] == str[j+k]) k++;
        height[_rank[i]] = k;
    }
}
char s[MAXN];
int str[MAXN], sa[MAXN], _rank[MAXN], height[MAXN];
int n, m;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",&s);
        int len =strlen(s);
        for( int i = 0; i < len; i++)
          str[i] = s[i];
        da(str, sa, _rank, height, len, 128);

        int ans = 0;

        for( int i = 1; i <= len; i++)
            ans += len - sa[i] - height[i];
        printf("%d\n",ans);
    }
    return 0;
}
内容概要:《中文大模型基准测评2025年上半年报告》由SuperCLUE团队发布,详细评估了2025年上半年中文大模型的发展状况。报告涵盖了大模型的关键进展、国内外大模型全景图及差距、专项测评基准介绍等。通过SuperCLUE基准,对45个国内外代表性大模型进行了六大任务(数学推理、科学推理、代码生成、智能体Agent、精确指令遵循、幻觉控制)的综合测评。结果显示,海外模型如o3、o4-mini(high)在推理任务上表现突出,而国内模型如Doubao-Seed-1.6-thinking-250715在智能体Agent和幻觉控制任务上表现出色。此外,报告还分析了模型性价比、效能区间分布,并对代表性模型如Doubao-Seed-1.6-thinking-250715、DeepSeek-R1-0528、GLM-4.5等进行了详细介绍。整体来看,国内大模型在特定任务上已接近国际顶尖水平,但在综合推理能力上仍有提升空间。 适用人群:对大模型技术感兴趣的科研人员、工程师、产品经理及投资者。 使用场景及目标:①了解2025年上半年中文大模型的发展现状与趋势;②评估国内外大模型在不同任务上的表现差异;③为技术选型和性能优化提供参考依据。 其他说明:报告提供了详细的测评方法、评分标准及结果分析,确保评估的科学性和公正性。此外,SuperCLUE团队还发布了多个专项测评基准,涵盖多模态、文本、推理等多个领域,为业界提供全面的测评服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值