(我还能怎样,能怎样,最后还不是像父亲一样把你原谅 ——鲁迅)

【简化题意】

给一个长度小于k的字符串和n个操作。
保证操作后字符串长度大于k,求最后的字符串中前k个字符。
操作规则如下:
给定一个(伪)区间[l,r],将区间中编号为奇数的字符形成一个新字符串,编号为偶数的字符形成一个字符串,将两个字符串拼接起来并放在编号为r字符的后边。
n<=5000,k<=3e6


【分析】

传统的思路上,不难发现我们只需要关心前k个字符即可。不需要多余的部分,然后就开心地水到了70分。
观察发现,超时的原因是因为我们产生了很多冗余的字符串,而这些字符串最终对答案并没有什么影响,产生了大量编号大于k的垃圾。
现在我们要避免产生垃圾,可以倒着往前做,求解密后的字符串第k位,和之前第几位是相同的,最终追溯到密文的那几位。再快速还原。先不求出具体的值,而是求出的问题中的拓扑关系。最终利用这个拓扑关系,快速还原出正解。

显然倒着做之后,确认过拓扑关系的点(也就是新产生的点)不会出现在上一步的字符串当中,所以要删除(或忽略),但是删除之后要重新拼接各个字符串并重新标号非常费时,所以我们考虑利用线段树来统计“在第i到第k位时有多少个数还未删除”,显然未删除的数就是当前状态下的编号。

【code】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=3e6+100;
struct Tree{int l,r,val;
}t[maxn<<2];
int l[maxn],r[maxn],qian[maxn];
char s[maxn],ans[maxn];
int n,k,p,q;
inline void read(int &x){x=0;int fl=1;char tmp=getchar();while(tmp<'0'||tmp>'9'){if(tmp=='-')fl=-fl;tmp=getchar();}while(tmp>='0'&&tmp<='9') x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();x=x*fl;
}
void build(int x,int l,int r){t[x].l=l,t[x].r=r,t[x].val=r-l+1;if(l==r) return ;int mid=l+r>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);
}
int change(int x,int l,int r,int y,int z){int mid;while(l<r){t[x].val-=z;mid=l+r>>1;if(t[x<<1].val<y)l=mid+1,y-=t[x<<1].val,x=(x<<1)+1;else r=mid,x=x<<1;}t[x].val-=z;return l;
}
int main(){freopen("father.in","r",stdin);freopen("father.out","w",stdout);scanf("%s",s+1);scanf("%d%d",&k,&n);for(int i=1;i<=n;i++)read(l[i]),read(r[i]);build(1,1,k);for(int j=n;j>=1;j--){if(r[j]>=t[1].val) continue;if(l[j]&1) p=l[j];else if(l[j]+1<=r[j]) p=l[j]+1;else p=l[j];for(int i=1;i<=r[j]-l[j]+1;i++){if(r[j]>=t[1].val) continue;q=change(1,1,k,r[j]+1,1);qian[q]=change(1,1,k,p,0);p+=2;if(p>r[j]){if(l[j]%2)p=l[j]+1;else p=l[j];}}}p=0;for(int i=1;i<=k;i++){if(qian[i])ans[i]=ans[qian[i]];else ans[i]=s[++p];putchar(ans[i]);}
}

奇洛金卡达 father.cpp相关推荐

  1. 【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)

    奇洛金卡达(father) Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗--与身为 人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade ...

  2. 【NOIP提高模拟】奇洛金卡达

    Description 阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗--与身为人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade的左右手. 奇洛金卡达.留着刺猬 ...

  3. JZOJ4708. 【NOIP2016提高A组模拟8.20】奇洛金卡达 倒着做的思想+并查集维护

    题目大意 给定一个长度小于等于kk的字符串和qq,表示现在有qq个操作,每个操作给定两个参数li,ril_i,r_i表示把现在的字符串第lil_i到rir_i把其中编号为奇数的按顺序写下来,再在后面把 ...

  4. C++中继承的基本概念

    文章目录 1 C++中继承的基本概念 1.1 继承的基本概念 1.2 继承的意义 1.3 继承实例分析 1 C++中继承的基本概念 1.1 继承的基本概念 继承关系就是父子关系,UML图如下: 注意是 ...

  5. C++设计模式实例讲解

    感言 本文很长,但文中近乎有十之八九只能算是我在拜读各位大神大牛们分享的作品的笔记,这里只是我第一遍学习,我知道过了几天我肯定又会把看过的东西给忘记,所以就索性把各位大牛们的东西整理到了一起,方便以后 ...

  6. 设计模式(C++实例)

    感言 本文很长,但文中近乎有十之八九只能算是我在拜读各位大神大牛们分享的作品的笔记,这里只是我第一遍学习,我知道过了几天我肯定又会把看过的东西给忘记,所以就索性把各位大牛们的东西整理到了一起,方便以后 ...

  7. C++:类的使用【析构函数】

    上章刚说到构造函数的一些基本用法,或许有人也会对取反的析构函数抱有疑问,这个函数有什么用呢? 析构函数的作用:当某个对象销毁时,执行一些特定的操作.比方说:指针成员占用的内存空间. 当然文字理解是个问 ...

  8. 英伟达TRTTorch

    英伟达TRTTorch PyTorch JIT的提前(AOT)编译Ahead of Time (AOT) compiling for PyTorch JIT TRTorch是PyTorch / Tor ...

  9. 吴恩达老师深度学习视频课笔记:逻辑回归公式推导及C++实现

    逻辑回归(Logistic Regression)是一个二分分类算法.逻辑回归的目标是最小化其预测与训练数据之间的误差.为了训练逻辑回归模型中的参数w和b,需要定义一个成本函数(cost functi ...

最新文章

  1. EXE 文件打不开的处理办法
  2. vsnprintf的作用和使用
  3. 面试:说说你对 Java 中 final 的理解?
  4. php实现单选和多选功能,input:checkbox多选框实现单选效果跟radio一样
  5. LeetCode 318. 最大单词长度乘积(位运算)
  6. devexpress 创建窗口句柄时出错_MATLAB函数句柄
  7. YII framework CComponent基础类解读(转)
  8. 只能选择GridView中的一个CheckBox(单选CheckBox)
  9. SSL-ZYC 2402 世界语
  10. MTK 驱动开发---Memory 移植
  11. vue项目中使用词云_如何在vue项目中使用高拍仪
  12. JavaWeb - 常用的HTTP请求头与响应头
  13. 人群密度分析算法调研
  14. Axure学习之简介
  15. CSDN(Markdown编辑)怎样打出各种表情符号和文章目录【图文】
  16. 解决 SysFader:iexplore.exe应用程序错误
  17. 美国林肯学院因遭勒索软件攻击后不堪重负被迫关闭
  18. 解决旧笔记本电脑的ME固件的驱动安装程序不支持WIN10安装的方法
  19. Mac配置ll的查看命令
  20. 通过usb利用adb实现android手机和pc机通信

热门文章

  1. Java 热更新 加载class和jar
  2. SAR chirp scaling(CSA)算法仿真
  3. 2000-2020年迪博上市公司内部控制指数
  4. windows和linux下简单的软件级调整相机曝光时间(或其他参数)的方式
  5. 整理后的IMF国际收支统计年鉴数据(2012-2018年)
  6. vue+antv L7实现高德地图自定义样式和自定义marker
  7. 锐捷S2952G-E V3 VSU(堆叠)原理及配置
  8. bootcdn中jQuery.print打印自动分页实现
  9. uci2019计算机录取,加州大学系统各分校公布2019年秋季入学录取数据!
  10. 设置response相应头用于浏览器下载文件