奇洛金卡达(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. Codeforces round 1103

    Div1 534 我可能还太菜了.jpg 果然我只是Div 2 选手 A (这题是Div1吗... 直接构造:竖着放的在第一行和第二行,然后横着放的时候直接放在第三行就行. #include < ...

  2. [Lydsy1805月赛]quailty 算法 BZOJ5362

    分析: 题目中描述了一个二分图,让我们求最小权最大匹配,实际上其实是求n个点,在n*(n-1)/2中选n条边的权值和最小,形成一个每个点都有出边的体系,也就是基环树,(证明:因为我们需要二分图最大匹配 ...

  3. Python3入门(六)——函数式编程

    一.高阶函数 1.可以通过变量指向函数,达到类似别名的效果: >>> f = abs >>> f(-10) 10 2.函数的参数可以是函数,也就是函数可以作为一个入 ...

  4. python基础3之文件操作、字符编码解码、函数介绍

    内容概要: 一.文件操作 二.字符编码解码 三.函数介绍 一.文件操作 文件操作流程: 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 基本操作: #/usr/bin/env ...

  5. Luogu P1196 [NOI2002]银河英雄传说

    一年没写博客了(滑稽). 这道题很玄学,导致自己都有一个坑人的问题求解.如果有大佬有能力求帮助:https://www.luogu.org/discuss/show?postid=30231 再来讲一 ...

  6. Windows下面的常用的快捷键

    最小化的快捷键: 最小化当前窗口:Alt+ESC 还原刚刚最小化的窗口:Alt+Tab(次快捷键组合可以在多个窗口中切换) 显示桌面,切换之前的桌面:Win+D   在浏览器页面之间切换:Ctrl+T ...

  7. vue-router单页应用简单示例(三)

    用vue-resource向服务器请求数据 我们主要来了解一下以下内容: 模拟服务端返回数据 用vue-resource向服务器请求数据 模拟服务器返回数据   我们用vue-cli创建的项目中,已经 ...

  8. dokuwiki 配置 sendmail 邮件发送

    dokuwiki 发送邮件有2种方式: 一是直接使用 PHP 自带发送功能,需要配置 PHP.ini 文件, 我没试过,可参考官网 https://www.dokuwiki.org/tips:mail ...

  9. C#_Winfrom将浏览器生成Image

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  10. C#_委托

    委托属于C#中的新名词,它的应用也非常广泛,例如事件就是委托最简单而又直接的例子. 那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言, ...