首页 > 其他分享 >P8796 [蓝桥杯 2022 国 AC] 替换字符

P8796 [蓝桥杯 2022 国 AC] 替换字符

时间:2022-11-04 21:46:04浏览次数:109  
标签:AC return rs int 线段 P8796 蓝桥 leq ls

题面

给定一个仅含小写英文字母的字符串 \(s\) 和 \(m\) 次操作,每次操作选择一个区间 \([l_i,r_i]\) 将 \(s\) 的该区间中的所有字母 \(x_i\) 全部替换成字母 \(y_i\),问所有操作做完后,得到的字符串是什么。

对于所有评测用例,\(1 \leq |s|, m \leq 10^5\),\(1 \leq l_i \leq r_i \leq |s|\),\(x_i\neq y_i\),其中 \(|s|\) 表示字符串 \(s\) 的长度。

思路

首先我写了一个蹩脚的 FHQ-Treap,后来被我证伪了……

其实这道题是一个线段树合并 / 分裂 水题。

首先先按照 \(s\) 的值域建出 \(26\) 棵线段树。对于每一个 \(s_i\),用第 \(s_i\) 个线段树将第 \(i\) 个元素修改为 \(1\)(也就是,存在)。

然后修改的时候直接将 \([l_i,r_i]\) 从第 \(x_i\) 个线段树上分裂下来,合并到第 \(y_i\) 个线段树上,也就可以了。

最后输出的时候暴力枚举值域,找到存在的输出即可。

时间复杂度 \(O(m\log|s_i|)\)。

另外本题有双倍经验 Codeforces911G Mass Change Queries,代码就不放了,具体看 Codeforces 提交记录

代码

#include <bits/stdc++.h>
#define int long long
#define ls(i) (t[i].ls)
#define rs(i) (t[i].rs)
#define mid ((l+r)>>1)
using namespace std;

const int N = 1e5+5;
struct node{
	int ls,rs,v;
} t[N<<8];
int root[30],tot;

inline void newnode(int &i){
	if(!i)i=(++tot);
}

void update(int p,int v,int &i,int l,int r){
	newnode(i);
	if(l==r){
		t[i].v=v;
		return;
	}
	if(p<=mid){
		update(p,v,ls(i),l,mid);
	}
	else{
		update(p,v,rs(i),mid+1,r);
	}
}

int split(int ql,int qr,int &i,int l,int r){
	int p=0;
	newnode(p);
	if(ql<=l&&r<=qr){
		t[p]=t[i];
		i=0;
	}
	else{
		if(ql<=mid){
			ls(p)=split(ql,qr,ls(i),l,mid);
		}
		if(qr>mid){
			rs(p)=split(ql,qr,rs(i),mid+1,r);
		}
	}
	return p;
}

void merge(int &x,int &y){
	if(x==0||y==0){
		if(y)x=y;
		if(x)y=x;
		return;
	}
	t[x].v+=t[y].v;
	merge(ls(x),ls(y));
	merge(rs(x),rs(y));
}

int query(int p,int i,int l,int r){
	if(!i)return 0;
	if(l==r){
		return t[i].v;
	}
	if(p<=mid){
		return query(p,ls(i),l,mid);
	}
	else{
		return query(p,rs(i),mid+1,r);
	}
}

char s[N];
int n,m;

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>(s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;i++){
		update(i,1,root[s[i]-'a'],1,n);
	}
	cin>>m;
	while(m--){
		int li,ri,x,y;char xi,yi;
		cin>>li>>ri>>xi>>yi;
		x=xi-'a',y=yi-'a';
		int ytxy_ak_ioi = split(li,ri,root[x],1,n);
		merge(root[y],ytxy_ak_ioi);
	}
	for(int i=1;i<=n;i++){
		for(char j='a';j<='z';j++){
			if(query(i,root[j-'a'],1,n)>0){
				cout<<j;
				break;
			}
		}
	}
	return 0;
	return 0;
}

AC Record

标签:AC,return,rs,int,线段,P8796,蓝桥,leq,ls
From: https://www.cnblogs.com/zheyuanxie/p/p8796.html

相关文章

  • oracle表字段设置为unused的相关知识
    文档课题:oracle表字段设置为unused的相关知识.数据库:oracle19.3表emp_test相关信息.SQL>selecttable_name,column_name,data_type,data_length,data_precision,data_scal......
  • 使用emplace_back的new initializer expression list treated as compound expression
    测试代码使用emplace_back可以避免不必要的构造和拷贝,而是直接在向量的内存位置执行construct进行构造,代码看起来也更加简洁。但是在使用的时候,会发现有一些和直观不太对......
  • 如何在proto3中用上golang对应的interface{}类型
    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客zhihuGithub公众号:一本正经的瞎扯首先,我希望所有golang中用于http请求响应的结构,都使用proto......
  • Oracle数据库知识总结
    一、Sql语句1.1查询语句order排序(其中含有null)查询雇员的奖金并做降序排序(关于nullsfirst/nullslast)​​​selectename,commfromemporderbycommdescnulls......
  • Apache shiro 反序列化漏洞
    Apacheshiro简介ApacheShiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从......
  • Linux安装Anaconda
    一、Linux安装AnacondaAnaconda官方下载地址:​​https://www.anaconda.com/products/individual#​​Linux运行$bashAnaconda3-2020.02-Linux-x86_64.sh#一路Enter#出现......
  • react组件传值
    1.父传子1.1父组件准备数据,父组件通过属性age直接传递给子组件父importReact,{useState}from'react'importChildsfrom'./Childs'exportdefaultfunctio......
  • [AcWing 788]逆序对的数量
    点击查看代码#include<iostream>usingnamespacestd;constintN=100010;intn;intq[N],tmp[N];typedeflonglongLL;//最坏情况下逆序数为n*(n-1)/2结......
  • openstack单机部署
    注:centos8单机版 注:本次实验手动配置密码均为admin环境准备:配置hosts文件192.168.116.8为本机IPecho'192.168.116.8controllervipmyip'>>/etc/hostsyumupgrad......
  • 洛谷P2730 [USACO3.2]魔板 Magic Squares
    题目链接:点这里 一般这种从某种状态转移到目标状态的最短距离,都可以使用BFS来做。从题目给定的初始状态,依次执行题目给定的三种操作,分别是交换上下两行(操作A)、将最后......