当前位置: 首页 > news >正文

2023.11.10联赛 T4题解

题目大意

题目思路

我们考虑分块处理。

我们可以维护一个状态,表示块内每个字母对应的真实字母,因为只有 3 3 3个字母,所以只有 6 6 6种情况。

对于每一个块,我们可以对于每种状态、每种块,预处理出以 A A A B B B C C C进入出来时是什么字母。

至此,思路就很明了。

修改操作对于散块直接修改,对于整块修改他们的状态。

查询操作对于散块直接跳,对于整块直接用预处理的信息跳即可。

具体实现参考代码。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,q,a[N],b[N],pos[N],posl[N],posr[N],g[N],sum[N][10][5],p[10][5],vis[5][5][5],block=0,tot=0;
char s[N],s1[200+10],s2[200+10];
int read()
{int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9')s=s*10+(ch-'0'),ch=getchar();return s*w;
}
int work(int l,int r,int state,int x)
{for(int i=l;i<=r;++i){int val=p[state][a[i]];if(x%3+1!=val)x=val;}return x;
}
void change(int l,int r,int val1,int val2)
{int x=0,y=0;for(int i=1;i<=3;++i)if(p[g[pos[l]]][i]==val1)x=i;    for(int i=1;i<=3;++i)if(p[g[pos[l]]][i]==val2)y=i; for(int i=l;i<=r;++i){if(p[g[pos[l]]][a[i]]==val1)a[i]=y;else if(p[g[pos[l]]][a[i]]==val2)a[i]=x;}for(int i=1;i<=6;++i)   for(int j=1;j<=3;++j)sum[pos[l]][i][j]=work(posl[pos[l]],posr[pos[r]],i,j);
}   
void update(int l,int r,int val1,int val2)
{if(pos[l]==pos[r]){change(l,r,val1,val2);return ;}change(l,posr[pos[l]],val1,val2);for(int i=pos[l]+1;i<=pos[r]-1;++i){int c[5];for(int j=1;j<=3;++j){if(p[g[i]][j]==val1)c[j]=val2;else if(p[g[i]][j]==val2)c[j]=val1;elsec[j]=p[g[i]][j];}g[i]=vis[c[1]][c[2]][c[3]];}change(posl[pos[r]],r,val1,val2);
}
int ask(int l,int r,int x)
{if(pos[l]==pos[r])return work(l,r,g[pos[l]],x);x=work(l,posr[pos[l]],g[pos[l]],x);for(int i=pos[l]+1;i<=pos[r]-1;++i)x=sum[i][g[i]][x];x=work(posl[pos[r]],r,g[pos[r]],x);return x;
}
int main()
{freopen("training.in","r",stdin);freopen("training.out","w",stdout);n=read(),q=read();scanf("%s",s+1);block=pow(n,2.0/5.0);for(int i=1;i<=n;++i)a[i]=s[i]-'A'+1,pos[i]=(i-1)/block+1;for(int i=1;i<=pos[n];++i){posl[i]=(i-1)*block+1;posr[i]=min(i*block,n);g[i]=1;}for(int i=1;i<=3;++i)b[i]=i;do{tot++;p[tot][1]=b[1];p[tot][2]=b[2];p[tot][3]=b[3];vis[b[1]][b[2]][b[3]]=tot;for(int i=1;i<=3;++i)for(int j=1;j<=pos[n];++j)sum[j][tot][i]=work(posl[j],posr[j],tot,i);}while(next_permutation(b+1,b+4));while(q--){int opt=read(),l=read(),r=read();if(opt==0){scanf("%s %s",s1+1,s2+1);update(l,r,s1[1]-'A'+1,s2[1]-'A'+1);            }else{scanf("%s",s1+1);printf("%c\n",ask(l,r,s1[1]-'A'+1)+'A'-1);}}return 0;
}

相关文章:

  • 一个“Hello, World”Flask应用程序
  • 冲突域、广播域、一些网络设备
  • 大容量疯了!居然想把磁带放到硬盘,100TB+是否可以实现?
  • 【Git】Git 学习笔记_操作远程仓库
  • ZYNQ_project:key_breath
  • 【实战-08】flink DataStream 如何实现去重
  • 技术分享 | Appium 用例录制
  • GZ038 物联网应用开发赛题第1套
  • 全志A40i应用笔记 | 3种常见的网卡软件问题以及排查思路
  • 前端-第一部分-HTML
  • pytorch(小土堆)深度学习
  • Python语法基础(条件语句 循环语句 函数 切片及索引)
  • 软件测试|MySQL BETWEEN AND:范围查询详解
  • flink1.18.0 macos sql-client.sh启动报错
  • 【2】Spring Boot 3 项目搭建
  • Android Volley源码解析
  • export和import的用法总结
  • java正则表式的使用
  • leetcode388. Longest Absolute File Path
  • leetcode46 Permutation 排列组合
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Promise面试题2实现异步串行执行
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Redis学习笔记 - pipline(流水线、管道)
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 阿里云应用高可用服务公测发布
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 高度不固定时垂直居中
  • 汉诺塔算法
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 浏览器缓存机制分析
  • 前端技术周刊 2019-01-14:客户端存储
  • 前端面试之CSS3新特性
  • 区块链将重新定义世界
  • 入口文件开始,分析Vue源码实现
  • 提醒我喝水chrome插件开发指南
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 昨天1024程序员节,我故意写了个死循环~
  • ​马来语翻译中文去哪比较好?
  • #{} 和 ${}区别
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (26)4.7 字符函数和字符串函数
  • (LeetCode) T14. Longest Common Prefix
  • (SpringBoot)第七章:SpringBoot日志文件
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)Dubbo快速入门、介绍、使用
  • (转)德国人的记事本
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .Net CoreRabbitMQ消息存储可靠机制