JZOJ #4708 / CODEFORCES #217 E.Alien DNA (逆向思维)

题目描述:

这题改编自CF217E,给出一串字符串,有$n$个操作,将区间$[l,r]$的字符中编号为奇数的写下,再把偶数的写在后面,然后把它们插入$r$和$r+1$之间,问最后字符串的前$k$位。

解题思路:

因为前面的操作不会对后面的操作有影响,所以我们考虑把操作倒过来做。相应的,一开始就只有$k$个位置有效,然后对于操作$[l,r]$,就把$[r+1,r+(r-l+1)]$标记为已操作,并记录每一位是哪一位转移过来的。然后对于前一个操作,就只能做那些未标记的位置。相当于对未标记的位置重标号,然后像刚刚一样继续做。当然,如果操作位置超出了当前未标记的位置,就不用做了。所以这样最多只要做$k$次。具体要怎么记录位置呢,可以用线段树,类似二分的找。在oj上被卡了线段树做法,所以改成非递归版卡过去了。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 3e6 + 10;
 7 int k, n, l[N], r[N], tr[N * 4], f[N];
 8 char s[N], ans[N];
 9 
10 void build(int o, int l, int r) {
11     tr[o] = r - l + 1;
12     if (l == r) return;
13     int m = l + r >> 1;
14     build(o << 1, l, m);
15     build(o << 1 | 1, m + 1, r);
16 }
17 
18 int find(int o, int l, int r, int k, int p) {
19     while (l != r) {
20         tr[o] -= p;
21         int m = l + r >> 1;
22         if (tr[o << 1] >= k) r = m, o <<= 1;
23         else k -= tr[o << 1], o = o << 1 | 1, l = m + 1; 
24     }
25     tr[o] -= p;
26     return l;
27 }
28 
29 void work() {
30     for (int i = n; i >= 1; i --) {
31         if (r[i] >= tr[1]) continue;
32         int t = l[i] & 1 ^ 1;
33         int now = l[i] + t;
34         if (now > r[i]) now = l[i] + (t ^ 1);
35         for (int j = 1; j <= r[i] - l[i] + 1 && r[i] < tr[1]; j ++) {
36             int p = find(1, 1, k, r[i] + 1, 1);
37             f[p] = find(1, 1, k, now, 0);
38             now += 2;
39             if (now > r[i]) now = l[i] + (t ^ 1);
40         }
41     }
42     for (int i = 1, j = 1; i <= k; i ++)
43         if (f[i]) ans[i] = ans[f[i]]; else ans[i] = s[j ++];
44     puts(ans + 1);
45 }
46 
47 int main() {
48     gets(s + 1);
49     scanf("%d %d", &k, &n);
50     build(1, 1, k);
51     for (int i = 1; i <= n; i ++) scanf("%d %d", &l[i], &r[i]);
52     work();
53     return 0;
54 }

 

转载于:https://www.cnblogs.com/awner/p/5796918.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值