倒序考虑每一个操作,对于一个操作$[l, r]$,他产生的影响区间将是$[r+1,r + r + l - 1]$,如果$r+l-1>K$的话,$K$之后的区间我们是不关心的。

暴力扫描这个区间 然后对于每一个位置,维护一个类似于并查集的东西。

扫到位置$i$,定义数组$f$ 表示$i$这个位置上的字符是由$f_i$这个位置上的字符填充得到的。然后删除$i$。

这个东西具体怎么搞?我们可以弄一个长度为K,初始化为1的序列。获得第$i$个位置就是这个序列上第$i$个1,然后删除这个位置上的字符,就是把序列上该位置的1变成0。维护这个序列的话树状数组+二分或者树状数组+倍增花式搞,我选择后者,毕竟前者复杂度多一个$log$。不会的话可以看lyd那本书的P203(第一版),或者做一下poj 2182.

当然线段树维护也是可以的啦~

所以我们就得到如下算法:

倒序扫描每一个操作,维护一个变量$now$表示我们关心的区间末尾,对于每次操作的区间$[l,r]$,用一个变量$x$扫描$[r+1,r+l-1]$所要填充的字符的位置。每填充一个数$now$就减一,如果$r>now$就直接停止。因为$now$的缘故,最多填充次数为$K$。每次填充时,设$tmp$为01序列中第$r+1$个1,那么将$tmp$位置上的数减一,然后更新$f_{tmp}$为第$x$个1的位置

然后从左往右求解,如果$f_i$存在,那么$ans_i=ans_{f_i}$,不然$ans_i=s_{j+1},j++$ 由于$f_i$必然比$i$小 所以这样做一定是正确的

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 3e6 + 10;
char s[N], ans[N];
int n, K, len, f[N], c[N];
struct OPT{ int l, r;}a[5050];
int lowbit(int x){ return x & -x;}
void add(int x, int val){
for(int i = x; i <= K; i += lowbit(i)) c[i] += val;
}
int get(int x){
int l = log2(K), sum = 0, ans = 0;
for(int i = l; i >= 0; i--){
int k = (1 << i);
if(ans + k <= K && sum + c[ans + k] < x)
sum += c[ans + k], ans += k;
}
return ans + 1;
}
int main(){
scanf("%s", s + 1);
scanf("%d%d", &K, &n);
for(int i = 1; i <= K; i++) c[i] = i & -i; //初始化树状数组为1
for(int i = 1; i <= n; i++) scanf("%d%d", &a[i].l, &a[i].r);
for(int now = K, i = n; i; i--)
for(int x = a[i].l + 1, j = 1; a[i].r < now && j <= a[i].r - a[i].l + 1; x += 2, j++, now--){
if(x > a[i].r) x = a[i].l;
int tmp = get(a[i].r + 1); add(tmp, -1), f[tmp] = get(x);
}
for(int i = 1, j = 0; i <= K; i++)
ans[i] = f[i] ? ans[f[i]] : s[++j];
puts(ans + 1);
return 0;
}

  

codeforces 217E 【Alien DNA】的更多相关文章

  1. Codeforces 176B【计数DP】

    题意: 给你两个串s1,s2和一个K, 有一种操作是在一个串切开然后交换位置, 问s1有多少种方法经过K次这样的操作变成s2: 思路: (从来没接触过计数DP...还是太菜...参考了[大牛blog] ...

  2. CodeForces 604D 【离散数学 置换群】

    题意: 给你一个方程,方程太变态不打,给你一个p一个k,p保证是大于等于3的质数,k保证在0~p-1之间的整数.要求对应函数的定义域在0~p-1值域为0~p-1的子集,求这样的函数有多少个... 分析 ...

  3. CodeForces 602D 【单调队列】【简单数学】

    题意: 给你n个数,m次询问,每次询问给l和r代表l和r中间所有子区间中特征值的和. 特征值的定义是在这个区间中找i和j使得|tmp[i]-tmp[j]|/|j-i|最大. 思路: 首先是特征值的定义 ...

  4. CodeForces 617C【序枚举】

    题意: 有两个点喷水,有很多个点有花,给出坐标. 求使得每个花都可以被喷到,两个喷水的半径的平方的和最小是多少. 思路: 枚举其中一个喷水的最大半径. 坑: 这题我贪心的思路有很大问题.一开始也是想这 ...

  5. CodeForces 602E【概率DP】【树状数组优化】

    题意:有n个人进行m次比赛,每次比赛有一个排名,最后的排名是把所有排名都加起来然后找到比自己的分数绝对小的人数加一就是最终排名. 给了其中一个人的所有比赛的名次.求这个人最终排名的期望. 思路: 渣渣 ...

  6. Codeforces | CF1029F 【Multicolored Markers】

    这道题其实难度应该小于紫题...除了一点小特判以外没什么难度...\(\leq50\)行代码即可\(AC\)此题 题目大意:给定两个数\(a,b(1\leq a,b\leq 10^{14})\)分别表 ...

  7. Codeforces | CF1037D 【Valid BFS?】

    题目大意:给定一个\(n(1\leq n\leq 2\cdot10^5)\)个节点的树的\(n-1\)条边和这棵树的一个\(BFS\)序\(a_1,a_2,\dots,a_n\),判断这个\(BFS\ ...

  8. Codeforces | CF1029C 【Maximal Intersection】

    论Div3出这样巨水的送分题竟然还没多少人AC(虽说当时我也没A...其实我A了D...逃) 这个题其实一点都不麻烦,排序都可以免掉(如果用\(priority \_ queue\)的话) 先考虑不删 ...

  9. Codeforces | CF1029D 【Concatenated Multiples】

    \(qwq\)昨天晚上\(Div.3\)过了这道题...早上交了\(1A\)...看在\(CF\)上\(hack\)的情况并不乐观而且也没人来交这题的份上...我决定发一篇题解帮\((zhuang)\ ...

随机推荐

  1. [C++]boost dijkstra获得两点间的最短路

    需求是只需要得到两点间的最短路,不需要求得单源对于全图的最短路,使用boost中的dijsktra_shortest_path,当得到目标点的最短路时直接throw exception. #inclu ...

  2. flex布局与ellipsis冲突问题

    在flex布局里使用text-overflow: ellipsis;发现没有省略. 解决方案 .g-flex-c{ flex: 1; min-width: 0; }

  3. 785. Is Graph Bipartite?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...

  4. 基础的Servlet

    1.认识Servlet 今天接触了Servlet,我就写了这篇Servlet的文章.首先,我们了解一下Servlet是什么: 这是百度百科的解释,我个人理解是可以用来前后端交互的一个东西,例如可以实现 ...

  5. elasticserach + kibana环境搭建

    一.java环境安装: 1.安装jdk,点击下一步即可. 2.环境变量配置 1) 找到jdk安装目录:C:\Program Files\Java\jdk1.8.0_161 2) 配置环境变量 ①找到环 ...

  6. hive 2以上版本启动异常 Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

    hive2.0以上的版本启动时 抛出 “Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreCli ...

  7. zookeeper的选举过程

    zookeeper的选举过程大致如下: zookeeper的选举过程,就是选出一个在n/2+1个节点中选出一个节点为主节点的过程.比如,当我们启动一个有5个节点的zookeeper集群的时候.首先启动 ...

  8. 20135208 JAVA第四次实验

    课程:Java程序与设计     班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩:             指导教师:娄嘉鹏     ...

  9. Junit4 单元测试框架的常用方法介绍

    Junit 介绍: Junit是一套框架(用于JAVA语言),由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),即 ...

  10. 20162328蔡文琛 week06

    20162328 2017-2018-1 <程序设计与数据结构>第6周学习总结 教材学习内容总结 队列元素按FIFO的方式处理----最先进入的元素最先离开. 队列是保存重复编码k值得一种 ...