首页 > 编程语言 >2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 J 前缀复制机

2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 J 前缀复制机

时间:2023-03-15 19:48:02浏览次数:55  
标签:std int len fa 上海理工大学 2023 GPLT include define

题目链接

https://ac.nowcoder.com/acm/contest/52244/J

对于给定的字符串s我们算出它每个位置能到达的前缀最大合法位置,然后进行dp即可
先对于s串求一遍kmp,然后建立boder树,在boder树上进行倍增查找最大合法位置
因为倍增查不到会返回0,但是0号点又是boder树的根节点,所以将boder树上点+1,然后查找合法最大合法位置的时候也会从查找小于等于pos / 2的第一个点变成查找小于等于(pos + 1) / 2的第一个点,我们求出接近(pos + 1) / 2的第一个不合法位置tw,然后fa[tw][0]就是最大的合法位置,最后进行一个简单的dp即可。

#include <iostream>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <stack>
#include <queue>
#include <numeric>
#include <cassert>
#include <bitset>
#include <cstdio>
#include <vector>
#include <unordered_set>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <deque>
#include <tuple>
#include <array>
 
#define all(a) a.begin(), a.end()
#define cnt0(x) __builtin_ctz(x)
#define endl '\n'
#define itn int
#define ll long long
#define ull unsigned long long
#define rep(i, a, b) for(int i = a;i <= b; i ++)
#define per(i, a, b) for(int i = a;i >= b; i --)
#define cntone(x) __builtin_popcount(x)
#define db double
#define fs first
#define se second
#define AC main(void)
#define HYS std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
typedef std::pair<int, int > PII;
typedef std::pair<int, std::pair<int, int>> PIII;
typedef std::pair<ll, ll> Pll;
typedef std::pair<double, double> PDD;
using ld = double long;

const long double eps = 1e-9;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10, M = 4e5 + 10;
int n , m;

struct KMP{
    int nxt[N];int len;
    char t[N];
    void clear(){
        len = nxt[0] = nxt[1] =0;
    }
    /* 1-bas */
    /* 注意在ss结尾添加‘\0’ */
    void init(char* ss){
        len = strlen(ss+1);
        memcpy(t, ss, (len + 2) * sizeof(char));
        for (int i = 2; i <= len; i ++){
            nxt[i] = nxt[i-1];
            while (nxt[i] && ss[i] != ss[nxt[i] + 1]) nxt[i] = nxt[nxt[i]];
            nxt[i] += (ss[i] == ss[nxt[i] + 1]);
        }
    }
    /* 求所有在ss串中的start_pos. 如果first_only设置为true,则只返回第一个位置*/
    std::vector<int> match(char *ss, bool first_only = false){
        int len_s = strlen(ss+1);
        std::vector<int> start_pos(0);
        for (int i = 1, j = 1; i <= len_s;){
            while (j !=1 && ss[i] != t[j]) j = nxt[j - 1] + 1;
            if (ss[i] == t[j]) j ++,i ++;
            else i ++;
            if (j == len + 1){
                start_pos.push_back(i - j + 1);
                if (first_only)return start_pos;
                j = nxt[len] + 1;
            }
        }
        return start_pos;
    }
    void debug(){
        for (int i = 0; i <= len; i ++){
            printf("[debug] nxt[%d]=%d\n", i, nxt[i]);
        }
    }
    /* 循环周期 形如 acaca 中 ac 是一个合法周期 */
    std::vector<int> periodic(){
        std::vector<int> ret;
        int now = len;
        while (now){
            now = nxt[now];
            ret.push_back(len - now);
        }
        return ret;
    }
    /* 循环节 形如 acac 中ac、acac是循环节,aca不是*/
    std::vector<int> periodic_loop(){
        std::vector<int>ret ;
        for (int x : periodic()){
            if (len % x == 0) ret.push_back(x);
        }
        return ret;
    }
    int min_periodic_loop(){
        return periodic_loop()[0];
    }
}kmp;

int h[N], e[N], ne[N], idx, root = 1, depth[N], fa[N][21], bw = 18, q[N];

void add(int a, int b){
	ne[idx] = h[a], e[idx] = b, h[a] = idx ++;
}
char str[N];

void bfs(){//初始化
    for(int i = 0; i <= n + 2; i ++)	depth[i] = 0x3f3f3f3f;
    int hh = 0, tt = 0;
    q[0] = root;//根节点入队
    depth[root] = 1, depth[0] = 0;
    while(hh <= tt){
        int f = q[hh ++];//取出队头
        for(int i = h[f]; ~i; i = ne[i]){//遍历邻边
            int j = e[i];
            if(depth[j] > depth[f] + 1){
                depth[j] = depth[f] + 1;
                q[++ tt] = j;
                fa[j][0] = f;
                for(int k = 1; k <= bw; k ++)
                    fa[j][k] = fa[fa[j][k-1]][k-1];
            }

        }
    }
}

int LCA(int a, int b){
    if(depth[a] < depth[b]) std::swap(a, b);//保持a的是深层
    //让a走到和b一样深的地方去
    for(int i = bw; i >= 0; i --)
        if(depth[fa[a][i]] >= depth[b])
            a = fa[a][i]; 
    if(a == b) return a;//说明b是a和b的公共祖先(不一定是最近公共祖先)
    //让a和b一起往上跳到最近公共祖先的先前一个点
    for(int i = bw; i >= 0; i -- ){
        if(fa[a][i] != fa[b][i]){
            a = fa[a][i];
            b = fa[b][i];
        }
    }

    return fa[a][0];
}
//本身不能是boder
int dp[N], top[N];

inline void solve(){
	std::cin >> n;
	std::cin >>(str + 1);
	kmp.init(str);
	kmp.clear();
	for(int i = 0; i <= n + 2; i ++)	h[i] = -1;
	auto nxt = kmp.nxt;

	for(int i = 1; i <= n; i ++)	add(nxt[i] + 1, i + 1);
	bfs();

	for(int i = 2; i <= n + 1; i ++){
		int j = (i + 1) / 2;
		int tw = i;
		for(int k = bw; ~k; k --){
			if(fa[tw][k] > j)	tw = fa[tw][k];	
		}
		top[i - 1] = fa[tw][0] - 1;
	}
	for (int i = 1; i <= n; i++) {
		if (top[i]) {
			dp[i] = std::min(dp[i - 1] + 1, dp[i - top[i]] + 1);
		} else {
			dp[i] = dp[i - 1] + 1;
		}
	}
	std::cout << dp[n] << '\n';
}

signed AC{
   	HYS
   	
	int _ = 1;
	std::cin >> _;
	while(_ --)
        solve();

    return 0;
}

标签:std,int,len,fa,上海理工大学,2023,GPLT,include,define
From: https://www.cnblogs.com/qdhys/p/17219705.html

相关文章

  • 2023年国漫前瞻:出海、漫改剧、元宇宙
    文|螳螂观察作者|青月谁读书的时候没有废寝忘食的看过一本漫画?那会,碰到一本有趣的漫画,真的是日夜奋战、如饥似渴。白天在课堂上,老师在上面讲,我们在下面急速浏览;晚上回到寝......
  • 【2023.03.15】是否要经过彻底的清算才能得到科技进步
    对国内的一些科研领域一直不报有太强的信心,昨晚在听马督公在讲征兵制引用《曹刿论战》的时候我终于豁然开朗,视频的链接放在这里。https://www.bilibili.com/video/BV18k4y1......
  • CVE-2023-22809 Sudoedit提权漏洞分析
    TRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChineseSimplifiedHungarianRussianC......
  • 2023秋招前端面试必会的面试题
    判断数组的方式有哪些通过Object.prototype.toString.call()做判断Object.prototype.toString.call(obj).slice(8,-1)==='Array';通过原型链做判断obj.__proto......
  • 2023,国产操作系统应用开发的路在何方?
    操作系统是为其它软件提供运行环境的硬件扩展,在整个系统中起着承上启下的作用。 对于国产操作系统, 顾名思义就是完全由我国自主研发的操作系统,比如鸿蒙(HarmonyOS)、深度D......
  • 2023/03/14(二)晴;叉烧肉+炸虾片
    大宝把学费的打款申请单拿回来了,日本老师把我不清楚的地方,都用便条写上内容贴了上去,做的很细致,很体贴;太周到了。得空儿要去银行办一下。 中午估计会加班,就给孩子们留言......
  • 2023秋招前端面试必会的面试题
    浏览器存储我们经常需要对业务中的一些数据进行存储,通常可以分为短暂性存储和持久性储存。短暂性的时候,我们只需要将数据存在内存中,只在运行时可用持久性存储,可以......
  • 2023年最新Pycharm免费安装教程
    今天我换了一台新电脑,作为一个Python爱好者,打算安装Pycharm。然而我发现之前使用的Pycharm版本并没有被传承到新电脑上,所以我决定安装最新的版本,即2022.3.3版。我记录了安......
  • CVPR2023 | 集成预训练金字塔结构的Transformer模型
    前言 本文提出了一种新的预训练模型架构(iTPN),该架构由多个金字塔形的Transformer层组成。每个层都包含多个子层,其中一些是普通的self-attention和feed-forward层,而另一些......
  • New!界面控件DevExpress WPF 2023产品路线图曝光
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专......