奇洛金卡达(father)

Description

阿良良木历将要迎来人生(不,是吸血鬼生涯)的第三次战斗——与身为
人类的奇洛金卡达在直江津高中的操场solo,以取回Heartunderblade 的左右
手。
奇洛金卡达。留着刺猬头、外形像神父的男子。靠着自身信仰,来消灭吸
血鬼的砖家。奇洛金卡达还是某个新兴宗教的大主教,那个宗教的教义,否定
了怪异的存在。
呐,在战斗之前,我们来研究一下那个新兴宗教的教义吧。教义被某种方
式加密成一个字符串,破译方式如下:
要按顺序执行n 个操作,第i 个操作由li,ri 两个正整数表示,意义为对
于当前字符串的[li,ri]区间,把其中编号为奇数的按顺序写下来,再在后面把
编号为偶数的按顺序写下来,最后把写出的新字符串加在区间后面。
为了更方便理解,举两个栗子:
1. s1s2s3s4s5s6s7 l=3 r=5
操作后变成:s1s2s3s4s5s3s5s4s6s7
2. s1s2s3s4s5s6s7 l=4 r=7

操作后变成:s1s2s3s4s5s6s7s5s7s4s6
n 次操作后,可以得到一个新的字符串。这个字符串可能很长,为了方便,
奇洛金卡达把这个字符串的前k 个字符作为教义。现在给出加密后的字符串,k,
和n 个操作,你能求出教义吗?

Input
第一行一个字符串s,表示加密后的字符串。
接下来一行两个整数k,n,接下来n 行,每行两个整数l,r,表示这个操作的
li,ri

Output
一行,表示最终得到字符串的前k 个字符

Simple Example

# input1:
baka
17 5
1 4
1 4
10 10
10 10
10 12
# output1:
bakabkaabkkkkkkaa

Data Constraint

30%:k≤5000
70%:k≤200000
100%:0≤n≤5000 1≤k≤3000000 1≤li,ri≤10^9 且范围不会超过当前
字符串长度,字符串由大写、小写字母组成。数据保证初始字符串长度不大于
m,最终字符串长度不小于m

Solution:

  • 我们要干什么(抽象出一个模型)

我们现在想知道原串S,经过n次操作后的处理串T,求T的前K位。

  • 我们能干什么?(拿拿暴力分)

正序模拟(超过K不管),复杂度O(nk),期望得分40-70

  • 还能干什么?

好像不行了!!!

有没有想过这种题目正着优化很难,正难则反~~

我们手里有原串S,什么都没有了。

一个显然的事实是最后的T串所有字符都是S中出现过的。(而且是一些奇怪的规律)

好吧我们假装T串求出来了(比S串长的多!)

且把所有询问读入,倒序往前尝试复原。

考虑到T和S串前面length(S)位一定是相等的。而且后面的每一位都可以对应的从前面转移得到,

进一步的,后面所有的元素一定是T串前length(S)通过一定关系被指向的!那么我们只需要知道这样一个拓扑序,

就可以复原整个T串了!

  • 10当L[i]是奇数时。

       R[i]是奇数的时候:奇数的个数一定是 (R[i]-L[i])/2+1,偶数的个数一定是(R-L)/2,所以一定是这种情况:

R[i]是偶数的时候:奇数的个数一定是(R[i]-L[i]+1)/2,偶数的个数一定是(R[i]-L[i]+1)/2,所以一定是这种情况:

  • 20当L[i]是偶数时。

R[i]是奇数的时候:奇数的个数一定是 (R[i]-L[i]+1)/2,偶数的个数一定是(R[i]-L[i]+1)/2,所以一定是这种情况:

R[i]是奇数的时候:奇数的个数一定是  (R[i]-L[i])/2+1,偶数的个数一定是(R-L)/2,所以一定是这种情况:

结论:当L[i]和R[i]奇偶性相异的时候,是这样的情况:

当L[i]和R[i]奇偶性相同的时候,是这样的情况:

定义 qian[i]表示第i个位置是从第qian[i]个位置转移而来(就是qian[i]和i等值,i和qian[i]的映射是qian数组),

可以经过上述讨论求出这个qian[i],一直求到最前端,然后一层层求出整个串T

然后我们发现通过上述处理后面的紫色到后面红色这一段是没有用的是不可能不知道,都可以从前面转移而来

将其删去。

我们定义线段树维护区间[l,r]中还有多少没有被删掉(可以被前面表示),

删去的话就是把从最后红色+1开始往后的所有元素区间减去要删数的个数(后面红色-中间紫色+1)

其实可以一个一个处理每次区间减-1!

最后按照拓扑序一个个还原就可以了!

# include<bits/stdc++.h>
using namespace std;
const int N=3e6+;
int t[*N],k,n;
int l[N],r[N],qian[N],ans[N];
char s[N];
void build(int x,int l,int r)
{
t[x]=r-l+;
if (l==r) return;
int mid=(l+r)/;
build(*x,l,mid);
build(*x+,mid+,r);
}
int change(int x,int l,int r,int y,int z)
{
int mid;
while (l<r) {
t[x]-=z;
mid=(l+r)/;
if (t[*x]<y) l=mid+,y-=t[*x],x=*x+;
else r=mid,x=*x;
}
t[x]-=z;
return l;
}
int p,q;
int main()
{
scanf("%s",s+);
scanf("%d%d",&k,&n);
for (int i=;i<=n;i++) scanf("%d%d",&l[i],&r[i]);
build(,,k);
for (int j=n;j>=;j--) {
if (r[j]>=t[]) continue;
if (l[j]%==) p=l[j];
else p=l[j]+; if (p>r[j]) {
if (l[j]%==) p=l[j]+; else p=l[j];
}
for (int i=;i<=r[j]-l[j]+;i++) {
if (r[j]>=t[]) continue;
q=change(,,k,r[j]+,);
qian[q]=change(,,k,p,);
p+=;
if (p>r[j]) {
if (l[j]%==) p=l[j]+; else p=l[j];
}
}
}
int j=;
for (int i=;i<=k;i++) {
if (qian[i]) ans[i]=ans[qian[i]];else ans[i]=s[++j];
putchar(ans[i]);
}
puts("");
return ;
}

【拓扑 字符串还原 + 线段树维护】奇洛金卡达(father)的更多相关文章

  1. cf580E. Kefa and Watch(线段树维护字符串hash)

    题意 $n$个数的序列,$m + k$种操作 1.$l , r, k$把$l - r$赋值为$k$ 2.$l, r, d$询问$l - r$是否有长度为$d$的循环节 Sol 首先有个神仙结论:若询问 ...

  2. 【NOIP模拟】board(线段树维护二进制,树序号化为二进制)

    题目背景 SOURCE:NOIP2016-RZZ-2 T3 题目描述 给出这样一棵“二叉树”: 每个节点有左右两个儿子,并如下定义每个节点的高度:假设父亲节点的高度为 h ,那么他的两个儿子的节点的高 ...

  3. 洛谷P4482 [BJWC2018]Border 的四种求法 字符串,SAM,线段树合并,线段树,树链剖分,DSU on Tree

    原文链接https://www.cnblogs.com/zhouzhendong/p/LuoguP4482.html 题意 给定一个字符串 S,有 q 次询问,每次给定两个数 L,R ,求 S[L.. ...

  4. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  5. hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

    传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131 ...

  6. CF - 1108 E 枚举上界+线段树维护

    题目传送门 枚举每个点作为最大值的那个点.然后既然是作为最大值出现的话,那么这个点就是不需要被减去的,因为如果最小值也在这个区间内的话,2者都减去1,对答案没有影响,如果是最小值不出现在这个区间内的话 ...

  7. 洛谷 P7879 -「SWTR-07」How to AK NOI?(后缀自动机+线段树维护矩乘)

    洛谷题面传送门 orz 一发出题人(话说我 AC 这道题的时候,出题人好像就坐在我的右侧呢/cy/cy) 考虑一个很 naive 的 DP,\(dp_i\) 表示 \([l,i]\) 之间的字符串是否 ...

  8. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  9. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

随机推荐

  1. Luogo P2324 [SCOI2005]骑士精神

    所有想练习A*的人都先来敲一下这道题吧. 数据范围即便只有5*5,但朴素的爆搜还是会超时. 因此考虑剪枝. 对于这道题,肯定只要进行最优化剪枝,判断现在走的步数+剩下最少要走的步数,如果大于ans或者 ...

  2. EZ 2017 01 07 t

    这名字诡异(然而就是这样) 这次主要是yekehe和yu‘ao都来了,所以很开心的讨论(上了200). 但是,yu’ao dalao又AK了!(666666) 不过总体难度也不高,主要是T3没思路. ...

  3. C标准库string.h中几个常用函数的使用详解

    strlen 计算字符串长度 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符. 函数实现: int Strlen(cons ...

  4. opengl学习记录1——矩形绘制

    #include <windows.h> #include <gl/GL.h> #include <gl/GLU.h> #include <glut.h> ...

  5. 后端自动构建前端css和js

    引子: 别的复杂前端开发技术不会,用得多的还是手写代码,手动处理. 3年前手写合并压缩js和css文件的asp脚本代码目前还能正常运行,也就没有多大使用别的技术的动力. 直到近期被一个问题纠结着,今天 ...

  6. Java开源博客My-Blog之docker容器组件化修改

    前言 5月13号上线了自己的个人博客,<Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦>,紧接着也在github上开源了博客的代码,到现在为 ...

  7. 网站遭受大量CC攻击后的应对策略

    上周开始我网站遭受了一大波CC攻击,到目前为止仍在继续,作为一个建站小白,我感觉压力好大,又有新的问题要挑战了! 服务器架设在腾讯云,CC攻击很凶猛,带宽瞬间占满,于是在腾讯云后台配置安全组关闭了80 ...

  8. (功能篇)回顾Bug管理系统Mantis优化改造经历

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  9. 关于k8s这项大动作,预示着边缘计算迎来“开源”发展的新周期……

    在文章<最近在边缘计算领域,发生了一件足以载入物联网史册的大事…>我曾经提到Kubernetes(简称K8s)将从超大规模云计算环境,被带入到物联网边缘计算场景中. 事情有了新进展,从本周 ...

  10. highcharts多个Y轴

    http://blog.sina.com.cn/s/blog_6a53599101019qax.html 多个Y轴的实现方法在于把yAxis设置成一个数组,里面的一个对象代表一条Y轴,利用opposi ...