P5251 [LnOI2019] 第二代图灵机 Solution

Description

给定序列 a = ( a 1 , a 2 , ⋯   , a n ) , b = ( b 1 , b 2 , ⋯   , b n ) a=(a_1,a_2,\cdots,a_n),b=(b_1,b_2,\cdots,b_n) a=(a1,a2,,an),b=(b1,b2,,bn) 和常数 c c c,有 m m m 个操作分四种:

  • set ⁡ ( x , v ) \operatorname{set}(x,v) set(x,v):执行 a x ← v a_x \gets v axv.
  • assign ⁡ ( l , r , k ) \operatorname{assign}(l,r,k) assign(l,r,k):对每个 i ∈ [ l , r ] i \in [l,r] i[l,r] 执行 b i ← k b_i \gets k bik.
  • query1 ⁡ ( l , r ) \operatorname{query1}(l,r) query1(l,r):求 min ⁡ [ u , v ] ∈ [ l , r ] , ∣ { b u , b u + 1 , ⋯   , b v } ∣ = c ( ∑ i = u v a i ) \min\limits_{[u,v] \in [l,r], |\{b_u,b_{u+1},\cdots,b_v\}|=c} (\sum\limits_{i=u}^v a_i) [u,v][l,r],{bu,bu+1,,bv}=cmin(i=uvai),若没有满足条件的区间,答案为 − 1 -1 1.
  • query2 ⁡ ( l , r ) \operatorname{query2}(l,r) query2(l,r):求 max ⁡ [ u , v ] ∈ [ l , r ] , ∣ { b u , b u + 1 , ⋯   , b v } ∣ = ( v − u + 1 ) ( ∑ i = u v a i ) \max\limits_{[u,v] \in [l,r], |\{b_u,b_{u+1},\cdots,b_v\}|=(v-u+1)} (\sum\limits_{i=u}^v a_i) [u,v][l,r],{bu,bu+1,,bv}=(vu+1)max(i=uvai).

Limitations

1 ≤ n , m ≤ 1 0 5 1 \le n,m \le 10^5 1n,m105
1 ≤ a i , v ≤ 1 0 4 1 \le a_i,v \le 10^4 1ai,v104
1 ≤ b i , k ≤ c ≤ 100 1 \le b_i,k \le c \le 100 1bi,kc100
1 ≤ l , r , x ≤ n ,    l ≤ r 1 \le l,r,x \le n,\;l \le r 1l,r,xn,lr
1 s , 256 MB 1\text{s},256\text{MB} 1s,256MB保证数据随机

Solution

显然可以用珂朵莉树维护 b b b,用线段树维护 a a a,需要支持单点改,区间和,最大,最小.
对于查询操作,由于 c c c 不大,可以直接对每种颜色开桶,然后在珂朵莉树上跑双指针,即可求出答案,具体见代码.

Code

6.23 KB , 1.20 s , 14.98 MB    (in   total,   C++20   with   O2) 6.23\text{KB},1.20\text{s},14.98\text{MB}\;\texttt{(in total, C++20 with O2)} 6.23KB,1.20s,14.98MB(in total, C++20 with O2)

// Problem: P5251 [LnOI2019] 第二代图灵机
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5251
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;

template<class T>
bool chmax(T &a, const T &b){
	if(a < b){ a = b; return true; }
	return false;
}

template<class T>
bool chmin(T &a, const T &b){
	if(a > b){ a = b; return true; }
	return false;
}

const int inf = 2e9;
struct Chtholly {
    int l, r;
    mutable int v;
    
    inline Chtholly() {}
    inline Chtholly(int _l, int _r, int _v): l(_l), r(_r), v(_v) {}
    
    inline bool operator<(const Chtholly& rhs) const {
        return l < rhs.l;
    }
};

struct Node {
    int l, r, sum, max, min;
};
inline int ls(int u) { return 2 * u + 1; }
inline int rs(int u) { return 2 * u + 2; }

struct SegTree {
    vector<Node> tr;
    inline SegTree() {}
    inline SegTree(const vector<int>& a) {
        const int n = a.size();
        tr.resize(n << 2);
        build(0, 0, n - 1, a);
    }
    
    inline void pushup(int u) {
        tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
        tr[u].max = std::max(tr[ls(u)].max, tr[rs(u)].max);
        tr[u].min = std::min(tr[ls(u)].min, tr[rs(u)].min);
    }
    
    inline void build(int u, int l, int r, const vector<int>& a) {
        tr[u].l = l;
        tr[u].r = r;
        if (l == r) {
            tr[u].sum = tr[u].max = tr[u].min = a[l];
            return;
        }
        const int mid = (l + r) >> 1;
        build(ls(u), l, mid, a);
        build(rs(u), mid + 1, r, a);
        pushup(u);
    }
    
    inline void set(int u, int p, int v) {
        if (tr[u].l == tr[u].r) {
            tr[u].sum = tr[u].max = tr[u].min = v;
            return;
        }
        const int mid = (tr[u].l + tr[u].r) >> 1;
        if (p <= mid) set(ls(u), p, v);
        else set(rs(u), p, v);
        pushup(u);
    }
    
    inline int sum(int u, int l, int r) {
        if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
        int ans = 0, mid = (tr[u].l + tr[u].r) >> 1;
        if (l <= mid) ans += sum(ls(u), l, r); 
        if (r > mid) ans += sum(rs(u), l, r);
        return ans;
    }
    
    inline int min(int u, int l, int r) {
        if (l <= tr[u].l && tr[u].r <= r) return tr[u].min;
        int ans = inf, mid = (tr[u].l + tr[u].r) >> 1;
        if (l <= mid) ans = std::min(ans, min(ls(u), l, r)); 
        if (r > mid) ans = std::min(ans, min(rs(u), l, r));
        return ans;
    }
    
    inline int max(int u, int l, int r) {
        if (l <= tr[u].l && tr[u].r <= r) return tr[u].max;
        int ans = 0, mid = (tr[u].l + tr[u].r) >> 1;
        if (l <= mid) ans = std::max(ans, max(ls(u), l, r)); 
        if (r > mid) ans = std::max(ans, max(rs(u), l, r));
        return ans;
    }
};

struct ODT {
    using It = set<Chtholly>::iterator;
    int n, c;
    set<Chtholly> odt;
    vector<int> vis;
    
    inline ODT() {}
    inline ODT(const vector<int>& a, int _c): n(a.size()), c(_c) {
        for (int i = 0; i < n; i++) odt.emplace(i, i, a[i]);
    }
    
    inline auto split(int p) {
        auto it = odt.lower_bound(Chtholly(p, -1, -1));
        if (it != odt.end() && it->l == p) return it;
        it--;
        int l = it->l, r = it->r, v = it->v;
        odt.erase(it);
        odt.emplace(l, p - 1, v);
        return odt.emplace(p, r, v).first;
    }
    
    inline void assign(int l, int r, int v) {
        auto itr = split(r + 1), itl = split(l);
        odt.erase(itl, itr);
        odt.emplace(l, r, v);
    }
    
    inline int query_all(int l, int r, SegTree& sgt) {
        vis.assign(c, 0);
        auto itr = split(r + 1), itl = split(l);
        auto ls = itl, rs = itl;
        int res = 1, ans = inf;
        vis[rs->v] = 1;
        
        while (rs != itr) {
            if (res == c) {
                if (ls == rs) ans = min(ans, sgt.min(0, ls->l, ls->r));
                else ans = min(ans, sgt.sum(0, ls->r, rs->l));
                vis[ls->v]--;
                res -= (vis[ls->v] == 0);
                ls++;
            }
            else {
                rs++;
                res += (vis[rs->v] == 0);
                vis[rs->v]++;
            }
        }
        return (ans == inf ? -1 : ans);
    }
    
    inline bool check(It itl, It itr) {
        if (itl == itr || next(itl) == itr) return false;
        for (auto it = next(itl); it != itr; it++) {
            if (it->l != it->r) return true;
        }
        return false;
    }
    
    inline int query_unique(int l, int r, SegTree& sgt) {
        vis.assign(c, 0);
        int ans = sgt.max(0, l, r);
        auto itr = split(r + 1), itl = split(l);
        auto ls = itl, rs = itl;
        for (; rs != itr; rs++) {
            vis[rs->v]++;
            while (check(ls, rs)) {
                vis[ls->v]--;
                ls++;
            }
            while (ls != rs && vis[rs->v] > 1) {
                vis[ls->v]--;
                ls++;
            }
            if (ls != rs) ans = max(ans, sgt.sum(0, ls->r, rs->l));
        }
        return ans;
    }
};

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int n, m, c;
	scanf("%d %d %d", &n, &m, &c);
	
	vector<int> a(n), b(n);
	for (int i = 0; i < n; i++) scanf("%d", &a[i]);
	for (int i = 0; i < n; i++) scanf("%d", &b[i]), b[i]--;
	
	SegTree seg(a);
	ODT odt(b, c);
	for (int i = 0, op, x, y, v; i < m; i++) {
	    scanf("%d", &op);
	    if (op == 1) {
	        scanf("%d %d", &x, &v); x--;
	        seg.set(0, x, v);
	    }
	    else if (op == 2) {
	        scanf("%d %d %d", &x, &y, &v);
	        x--, y--, v--;
	        odt.assign(x, y, v);
	    }
	    else if (op == 3) {
	        scanf("%d %d", &x, &y);
	        x--, y--;
	        printf("%d\n", odt.query_all(x, y, seg));
	    }
	    else if (op == 4) {
	        scanf("%d %d", &x, &y);
	        x--, y--;
	        printf("%d\n", odt.query_unique(x, y, seg));
	    }
	}
	
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flutter 专题四十七 Flutter 应用启动流程分析

众所周知&#xff0c;任何应用程序的启动都是从main()函数开始的&#xff0c;Flutter也不例外&#xff0c;main.dart文件的main函数开始的&#xff0c;代码如下。 void main() > runApp(MyApp());main函数则调用的是runApp函数&#xff0c;源码如下。 void runApp(Widget …

html中的表格属性以及合并操作

表格用table定义&#xff0c;标签标题用caption标签定义&#xff1b;用tr定义表格的若干行&#xff1b;用td定义若干个单元格&#xff1b;&#xff08;当单元格是表头时&#xff0c;用th标签定义&#xff09;&#xff08;th标签会略粗于td标签&#xff09; table的整体外观取决…

大语言模型轻量化:知识蒸馏的范式迁移与工程实践

大语言模型轻量化&#xff1a;知识蒸馏的范式迁移与工程实践 &#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 摘要 在大型语言模型&#xff…

Go语言的转义字符

文章目录 1. Go语言的转义字符(escapechar)2. 小结和提示 1. Go语言的转义字符(escapechar) 说明:常用的转义字符有如下: \t : 表示一个制表符&#xff0c;通常使用它可以排版\n &#xff1a;换行符\\ &#xff1a;一个\\" &#xff1a;一个"\r &#xff1a;一个回…

Docker深度解析:容器与容器局域网

DockerFile 解析&#xff1a; DockerFile 描述出镜像文件需要的一些依赖配置和环境变量执行命令 docker build&#xff0c;将我们的 dockerfile 文件打包成一个镜像文件直接使用我们的容器运行到该镜像文件 CentOS 镜像&#xff1a; 运行镜像&#xff1a; docker run -it cent…

360手机刷机 360手机解Bootloader 360手机ROOT

360手机刷机 360手机解Bootloader 360手机ROOT 问&#xff1a;360手机已停产&#xff0c;现在和以后&#xff0c;能刷机吗&#xff1f; 答&#xff1a;360手机&#xff0c;是肯定能刷机的 360手机资源下载网站 360手机-360手机刷机RootTwrp 360os.top 360rom.github.io 一、…

C++输入输出(上)

cin和cout cin是C中提供的标准输入流对象,一般针对的是键盘,也就是从键盘上输入的字符流,使用 cin来进行数据的提取,cin一般是和 >> (流提取运算符) 配合使用的。 cin的功能和scanf是类似的 cout是C中提供的标准输出流对象,一般针对的是控制台的窗口,也就是将数据以字符…

【沐风老师】3DMAX混沌破碎插件ChaosFracture使用方法

3DMAX混沌破碎插件ChaosFracture&#xff0c;只需一键操作&#xff0c;即可轻松实现物体的破碎效果&#xff0c;同时确保外表面与内部断裂部分保持原有的材质ID和UVs信息&#xff0c;真实呈现细腻的破碎场景。 【适用版本】 3DMax9及更高版本&#xff08;建议使用3DMax2018以上…

e2studio开发RA2E1(8)----GPT定时器频率与占空比的设置

e2studio开发RA2E1.8--GPT定时器频率与占空比的设置 概述视频教学样品申请硬件准备参考程序源码下载选择计时器时钟源PWM(脉冲宽度调制)R_GPT_PeriodSet()函数说明R_GPT_DutyCycleSet()函数说明R_GPT_Reset()函数说明R_GPT_Close() 函数说明主程序波形情况 概述 GPT&#xff0…

7.PPT:“中国梦”学习实践活动【20】

目录 NO1234​ NO5678​ NO9\10\11 NO1234 考生文件夹下创建一个名为“PPT.pptx”的新演示文稿Word素材文档的文字&#xff1a;复制/挪动→“PPT.pptx”的新演示文稿&#xff08;蓝色、黑色、红色&#xff09; 视图→幻灯片母版→重命名&#xff1a;“中国梦母版1”→背景样…

基于Flask的大模型岗位招聘可视化分析系统的设计与实现

【FLask】基于Flask的大模型岗位招聘可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言&#xff0c;结合Echarts可视化库&#xff0…

AlwaysOn 可用性组副本所在服务器以及该副本上数据库的各项状态信息

目录标题 语句代码解释:1. `sys.dm_hadr_database_replica_states` 视图字段详细解释及官网链接官网链接字段解释2. `sys.availability_replicas` 视图字段详细解释及官网链接官网链接字段解释查看视图的创建语句方法一:使用 SQL Server Management Studio (SSMS)方法二:使用…

windows版的docker如何使用宿主机的GPU

windows版的docker使用宿主机的GPU的命令 命令如下 docker run -it --nethost --gpus all --name 容器名 -e NVIDIA_DRIVER_CAPABILITIEScompute,utility -e NVIDIA_VISIBLE_DEVICESall 镜像名效果 (transformer) rootdocker-desktop:/# python Python 3.9.0 (default, Nov 15 …

知识蒸馏教程 Knowledge Distillation Tutorial

来自于&#xff1a;Knowledge Distillation Tutorial 将大模型蒸馏为小模型&#xff0c;可以节省计算资源&#xff0c;加快推理过程&#xff0c;更高效的运行。 使用CIFAR-10数据集 import torch import torch.nn as nn import torch.optim as optim import torchvision.tran…

K8S集群部署--亲测好用

最近在自学K8S&#xff0c;花了三天最后终于成功部署一套K8S Cluster集群&#xff08;masternode1node2&#xff09; 在这里先分享一下具体的步骤&#xff0c;后续再更新其他的内容&#xff1a;例如部署期间遇到的问题及其解决办法。 部署步骤是英文写的&#xff0c;最近想练…

【Unity2D 2022:UI】创建滚动视图

一、创建Scroll View游戏对象 在Canvas画布下新建Scroll View游戏对象 二、为Content游戏对象添加Grid Layout Group&#xff08;网格布局组&#xff09;组件 选中Content游戏物体&#xff0c;点击Add Competent添加组件&#xff0c;搜索Grid Layout Group组件 三、调整Grid La…

c++:list

1.list的使用 1.1构造 1.2迭代器遍历 &#xff08;1&#xff09;迭代器是算法和容器链接起来的桥梁 容器就是链表&#xff0c;顺序表等数据结构&#xff0c;他们有各自的特点&#xff0c;所以底层结构是不同的。在不用迭代器的前提下&#xff0c;如果我们的算法要作用在容器上…

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1&#xff1a;如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」&#xff0c;deepseek便爆火 爆火以后便应了“人红是非多”那句话&#xff0c;不但遭受各种大规模攻击&#xff0c;即便…

游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文

Unity Unity 首次发布于 2005 年&#xff0c;属于 Unity Technologies Unity 使用的开发技术有&#xff1a;C# Unity 的适用平台&#xff1a;PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域&#xff1a;开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

[权限提升] Windows 提权 维持 — 系统错误配置提权 - 注册表权限配置错误提权

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;注册表权限配置错误提权原理 通常 Windows 中的服务都是以 System 权限运行的&#xff0c;而 Windows 的服务程序的启动路径又是存放在注册表中的&#xff0c;若注册表配置不…