题目传送门(内部题60)


输入格式

第一行三个数$n,m,k$。
第二行一个长度为$n$的串。
接下来$m$行每行两个数$L_i$和$R_i$。


输出格式

一个串,表示字典序第$k$小的合法的能被填出的串。


样例

样例输入:

12 1 4
ztrs?a?isred
5 7

样例输出:

ztrsdadisred


数据范围与提示

对于$10\%$的数据,保证$n,m\leqslant 100$。
对于$30\%$的数据,保证$n,m\leqslant 5,000$。
对于另外$10\%$的数据(包含于$70\%$的数据),保证$n\leqslant 5,000$。
对于另外$10\%$的数据(包含于$70\%$的数据),保证$m\leqslant 5,000$。
对于$70\%$的数据,保证$n,m\leqslant 5\times {10}^4$。
对于另外$10\%$的数据,保证$k\leqslant 100$。
对于$100\%$的数据,保证$n,m\leqslant 5\times {10}^5,k\leqslant 1\times {10}^{18}$。


题解

先不考虑区间反转的复杂度问题,只考虑翻转之后如何统计答案。

这时候会出现有些位必须是一样的,这时候如果其中有一位是字符,那么这些位必须都是一个字符;当然不会出现两种不同的字符,因为这样就无解了。

接着考虑第$k$小的问题,显然我们只能从有些位是一样的并且其中没有字符的做手脚,因为它们是可以随便赋值的,而字符串的字典序的大小取决于它们中位置最靠前的;那么现在假设有$p$个位置可以随意赋成不一样的值,那么我们也就是将$k$转化成$26$进制,然后从后往前,从低位往高位给串赋值,剩下的都赋成$a$即可。

这道题出题人卡了$rope$的常,导致无旋$Treap$和单旋$Splay$都也被卡了;然而我打的就是$Splay$,所以我卡了好长时间的常;第一个$A$掉这道题的也说是评测机哆嗦了一下,再交一遍就不行了。那么我下面讲一下我的卡常心得,部分有关卡常代码在下方“代码时刻”中给出。

  $\alpha.register$显然必不可少。

  $\beta.$快读$+fread$。$fread\downarrow$

const int L=1<<20|1;
char buffer[L],*S,*T;
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)

  $\gamma.$老师不让用全局$O3$,于是我可以在代码中手开了部分$O3$。对于函数的$O3\downarrow$

#define inline  __attribute__((optimize("-O3")))

  $\delta.bool$和部分值域较小变量换成$char$,这将让你的代码跑的飞快。

  $\epsilon.$局部变量不要开全局。

  $\zeta.$另外对于$HZOI$的小朋友们,可以使用连续提交的策略,让评测机预热一下,一般情况下五遍以内就过了。

有了这些卡常工具,你就可以轻松$AC$此题了。

下面给出我在这道题的卡常历程,一共$38$次$TLE\downarrow$

不过结局总是好的$downarrow$

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$80\sim 100$分(看你怎么卡常了)。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int L=1<<20|1;
char buffer[L],*S,*T;
#define inline __attribute__((optimize("-O3")))
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
inline int Read(){
register int ret;
register char r;
while(r=getchar(),r<'0'||r>'9');ret=r-48;
while(r=getchar(),r>='0'&&r<='9')ret=(ret<<3)+(ret<<1)+r-48;
return ret;
}
int n,m;
long long K,bas[15];
char ch[500005],ans[500005];
int trfat[500005],trson[500005][2],trsiz[500005];
char trlaz[500005];
int root;
int b[500005],bel[500005],block,st[500005];
char vis[500005];
inline void pushup(register int x){trsiz[x]=trsiz[trson[x][0]]+trsiz[trson[x][1]]+1;}
inline void pushdown(register int x)
{
if(x&&trlaz[x])
{
trlaz[trson[x][0]]^=1;
trlaz[trson[x][1]]^=1;
swap(trson[x][0],trson[x][1]);
trlaz[x]=0;
}
}
inline void build(register int father,register int l,register int r)
{
if(l>r)return;
register int mid=(l+r)>>1;
trfat[mid]=father;
mid>father?trson[father][1]=mid:trson[father][0]=mid;
build(mid,l,mid-1);
build(mid,mid+1,r);
pushup(mid);
}
inline void rotate(register int x)
{
register int father=trfat[x];
register int grandf=trfat[father];
register char myself=trson[trfat[x]][1]==x;
pushdown(father);
pushdown(x);
if(grandf)trson[grandf][trson[trfat[father]][1]==father]=x;
trson[father][myself]=trson[x][myself^1];
trfat[trson[father][myself]]=father;
trson[x][myself^1]=father;
trfat[father]=x;
trfat[x]=grandf;
pushup(father);
pushup(x);
}
inline void splay(register int x,register int k)
{
for(register int father;(father=trfat[x])!=k;rotate(x))
if(trfat[father]!=k)rotate((trson[trfat[x]][1]==x)==(trson[trfat[father]][1]==father)?father:x);
if(!k)root=x;
}
inline int rank(register int x)
{
register int now=root;
while(1)
{
pushdown(now);
if(x<=trsiz[trson[now][0]])now=trson[now][0];
else
{
x-=trsiz[trson[now][0]]+1;
if(!x)return now;
now=trson[now][1];
}
}
}
inline void turn(register int l,register int r)
{
l=rank(l);
r=rank(r+2);
splay(l,0);
splay(r,l);
pushdown(root);
trlaz[trson[trson[root][1]][0]]^=1;
}
inline int get_pow(register long long x)
{
register int lft=0,rht=14,res=0;
while(lft<=rht)
{
int mid=(lft+rht)>>1;
bas[mid]<=x?lft=mid+1,res=mid:rht=mid-1;
}
return res;
}
inline void work()
{
scanf("%d%d%lld",&n,&m,&K);
scanf("%s",ch+1);
K--;bas[0]=1;
for(register int i=1;i<15;i++)bas[i]=bas[i-1]*26;
build(0,1,n+2);root=(n+3)>>1;
while(m--)
{
register int l=Read(),r=Read();
turn(l,r);
}
for(register int i=1;i<=n;i++)
b[i]=rank(i+1)-1;
for(register int i=1;i<=n;i++)
if(!bel[i])
{
block++;
int x=i;
while(!bel[x])
{
bel[x]=block;
x=b[x];
}
}
register int top=0;
for(register int i=1;i<=n;i++)
if(ch[i]!='?')ans[bel[i]]=ch[i];
for(register int i=1;i<=n;i++)
if(!ans[bel[i]]&&!vis[bel[i]])
{
vis[bel[i]]=1;
st[++top]=bel[i];
}
while(K)
{
register int x=get_pow(K);
ans[st[top-x]]='a'+K/bas[x];
K-=bas[x]*(K/bas[x]);
}
for(register int i=1;i<=top;i++)
if(!ans[st[i]])ans[st[i]]='a';
for(register int i=1;i<=n;i++)
putchar(ans[bel[i]]);
}
int main()
{
work();
return 0;
}

rp++

[CSP-S模拟测试]:string(文艺平衡树)的更多相关文章

  1. [CSP-S模拟测试]:string(线段树)

    题目描述 给定一个由小写字母组成的字符串$s$. 有$m$次操作,每次操作给定$3$个参数$l,r,x$. 如果$x=1$,将$s[l]~s[r]$升序排序: 如果$x=0$,将$s[l]~s[r]$ ...

  2. [CSP-S模拟测试]:String Master(暴力)

    题目描述 所谓最长公共子串,比如串$A:"abcde"$,串$B:"jcdkl"$,则它们的最长公共子串为串$"cd"$,即长度最长的字符串 ...

  3. csp-s模拟测试b组加餐antipalindome,randomwalking,string题解

    题面:https://www.cnblogs.com/Juve/articles/11599318.html antipalindome: 打表找规律? 对于一个回文串,我们只要保证3位以内不回文即可 ...

  4. Android单元测试与模拟测试详解

    测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabri ...

  5. [开源]微信在线信息模拟测试工具(基于Senparc.Weixin.MP开发)

    目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具 ...

  6. Mockito:一个强大的用于Java开发的模拟测试框架

    https://blog.csdn.net/zhoudaxia/article/details/33056093 介绍 本文将介绍模拟测试框架Mockito的一些基础概念, 介绍该框架的优点,讲解应用 ...

  7. Mock 模拟测试简介及 Mockito 使用入门

    Mock 是什么mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法.这个虚拟的对象就是mock对象.mock对象就是真实对象在调试期间的代 ...

  8. 模拟测试—moq:简单一两句

    在Xunit的基础上,说话模拟测试. 假如我们有这样一个控制器里面有这样一个方法,如图 我们在对Bar测试得时候,如果测试未通过,错误有可能来至于Bar,也有可能错误来至于serverde Foo方法 ...

  9. springboot2.0入门(四)----mock模拟测试+单元测试

    一.本节主要记录模拟测试.单元测试: 二.mock 测试 1.1什么是Mock? 在面向对象程序设计中,模拟对象(英语:mock object,也译作模仿对象)是以可控的方式模拟真实对象行为的假的对象 ...

随机推荐

  1. php 的定界符 <<<eof 的问题

    PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法 ——按字符串输出的话,肯定要有大量的转义符来对字符串中的引号等特 ...

  2. Minimum Cost 【POJ - 2516】【网络流最小费用最大流】

    题目链接 题意: 有N个商家它们需要货物源,还有M个货物供应商,N个商家需要K种物品,每种物品都有对应的需求量,M个商家每种物品都是对应的存货,然后再是K个N*M的矩阵表示了K个物品从供货商运送到商家 ...

  3. JNDI配置笔记

    先在tomcat Context.xml配置文件中配置 <Resource name="jdbc/elifecrm" type="javax.sql.DataSou ...

  4. 微信小程序(二)--逻辑层与界面层

    一.逻辑层与界面层分离 小程序开发框架将我们需要完成的编码,划分成了两种类型的编码:逻辑编码(由JavaScript完成,业务数据供给界面事件处理),界面编码(页面结构WXML,页面样式WXSS,展示 ...

  5. jvm学习(3)方法区、堆、对象存储位置

    方法区 方法区,Method Area, 对于习惯在HotSpot虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价, ...

  6. Manacher(输出最长回文串及下标)

    http://acm.hdu.edu.cn/showproblem.php?pid=3294 Girls' research Time Limit: 3000/1000 MS (Java/Others ...

  7. StatusStrip 分类: C# 2015-07-23 11:58 2人阅读 评论(0) 收藏

    通过StatusStrip显示窗体状态栏 同时将状态栏分成三部分 居左边显示相关文字信息 中间空白显示 居右边显示时间信息 1.创建窗体及添加StatusStrip   默认StatusStrip名称 ...

  8. Windows程序设计--(三)窗口与消息

    3.1 窗口的创建 3.1.1 系统结构概述 所谓「Windows给程序发送消息」,是指Windows呼叫程序中的一个函数,该函数的参数描述了这个特定消息.这种位于Windows程序中的函数称为「窗口 ...

  9. zabbix3.0自动发现磁盘并监控磁盘IO

    Zabbix 版本:3.0 操作系统:Ubuntu16.04 操作环境,在被监控的主机上安装zabbix agent.安装方式为源码包安装. 简要安装步骤: 参考:https://www.zabbix ...

  10. 第十五章 Kubernetes调度器

    一.简介 Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上.听起来非常简单,但有很多要考虑的问题: ① 公平:如何保证每个节点都能被分配资源 ② ...