关闭

CodeForces - 145E - Lucky Queries(线段树[区间合并])

标签: 线段树
101人阅读 评论(0) 收藏 举报
分类:

题意:

告诉你一个4和7 的序列

两种操作:

1. 讲区间的数反转(即4变7  7变4)

2。 输出总区间中   非递减子序列的长度。


思路:

注意:子序列是可以不连续的


很明显是线段树了。

统计4的长度。

统计7 的长度。

统计4开头 7结尾的长度。

然后就是简单的区间合并问题了。

因为涉及区间反转,所以 可以在开同样的变量 记录反转后 4 的长度, 反转后7的长度, 反转后47的长度。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;


const int maxn = 1000000 + 10;

struct node{
    int l,r;
    int len4[2], len7[2], len47[2];
    int ans;
    int rev;
    int len;
}nod[maxn<<2];

char s[maxn];
char cmd[20];

void pushup(int o){
    int lson = o << 1;
    int rson = o << 1 | 1;
    nod[o].len4[0] = nod[lson].len4[0] + nod[rson].len4[0];
    nod[o].len7[0] = nod[lson].len7[0] + nod[rson].len7[0];
    nod[o].len47[0] = 0;
    nod[o].len47[0] = max(nod[lson].len4[0] + nod[rson].len7[0], nod[o].len47[0]);
    nod[o].len47[0] = max(nod[lson].len4[0] + nod[rson].len47[0], nod[o].len47[0]);
    nod[o].len47[0] = max(nod[lson].len47[0] + nod[rson].len7[0], nod[o].len47[0]);
    nod[o].ans = 0;
    nod[o].ans = max(nod[o].ans, nod[o].len4[0]);
    nod[o].ans = max(nod[o].ans, nod[o].len7[0]);
    nod[o].ans = max(nod[o].ans, nod[o].len47[0]);


    ///========================


    nod[o].len4[1] = nod[lson].len4[1] + nod[rson].len4[1];
    nod[o].len7[1] = nod[lson].len7[1] + nod[rson].len7[1];
    nod[o].len47[1] = 0;
    nod[o].len47[1] = max(nod[lson].len4[1] + nod[rson].len7[1], nod[o].len47[1]);
    nod[o].len47[1] = max(nod[lson].len4[1] + nod[rson].len47[1], nod[o].len47[1]);
    nod[o].len47[1] = max(nod[lson].len47[1] + nod[rson].len7[1], nod[o].len47[1]);
}


void deal(int o){
    nod[o].rev ^= 1;
    swap(nod[o].len4[0], nod[o].len4[1]);
    swap(nod[o].len7[0], nod[o].len7[1]);
    swap(nod[o].len47[0], nod[o].len47[1]);
    nod[o].ans = 0;
    nod[o].ans = max(nod[o].ans, nod[o].len4[0]);
    nod[o].ans = max(nod[o].ans, nod[o].len7[0]);
    nod[o].ans = max(nod[o].ans, nod[o].len47[0]);
}
void pushdown(int o){

    if (nod[o].rev){
        deal(o<<1);
        deal(o<<1|1);
        nod[o].rev = 0;
    }
}

void build(int l,int r,int o){
    nod[o].l = l;
    nod[o].r = r;
    nod[o].rev = 0;
    nod[o].len = r - l + 1;
    if (l == r){
        if (s[l] == '4'){
            nod[o].len4[0] = 1;
            nod[o].len7[0] = 0;
            nod[o].len47[0] = 0;

            nod[o].len4[1] = 0;
            nod[o].len7[1] = 1;
            nod[o].len47[1] = 0;
            nod[o].ans = 1;
            return;
        }
        else {
            nod[o].len4[0] = 0;
            nod[o].len7[0] = 1;
            nod[o].len47[0] = 0;

            nod[o].len4[1] = 1;
            nod[o].len7[1] = 0;
            nod[o].len47[1] = 0;
            nod[o].ans = 1;
            return;
        }
    }


    int m = l + r >> 1;
    build(l, m, o << 1);
    build(m+1, r, o<<1|1);
    pushup(o);
}



void update(int L,int R,int l,int r,int o){
    if (L <= l && r <= R){
        deal(o);
        return;
    }
    pushdown(o);

    int m = l + r >> 1;
    if (m >= L){
        update(L, R, l, m, o<<1);
    }
    if (m < R){
        update(L, R, m+1, r, o<<1|1);
    }
    pushup(o);
}



int main(){

    int n,q;
    scanf("%d %d", &n, &q);

    scanf("%s", s+1);
    build(1, n, 1);

    while(q--){
        scanf("%s", cmd);
        if (cmd[0] == 'c'){
            printf("%d\n", nod[1].ans);
        }
        else {
            int x,y;
            scanf("%d %d", &x, &y);
            update(x, y, 1, n, 1);
        }
    }



    return 0;
}

E. Lucky Queries
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal record contains only the lucky digits 4 and 7. For example, numbers 477444 are lucky and 517467 are not.

Petya brought home string s with the length of n. The string only consists of lucky digits. The digits are numbered from the left to the right starting with 1. Now Petya should execute m queries of the following form:

  • switch l r — "switch" digits (i.e. replace them with their opposites) at all positions with indexes from l to r, inclusive: each digit 4 is replaced with 7 and each digit 7 is replaced with 4 (1 ≤ l ≤ r ≤ n);
  • count — find and print on the screen the length of the longest non-decreasing subsequence of string s.

Subsequence of a string s is a string that can be obtained from s by removing zero or more of its elements. A string is called non-decreasing if each successive digit is not less than the previous one.

Help Petya process the requests.

Input

The first line contains two integers n and m (1 ≤ n ≤ 106, 1 ≤ m ≤ 3·105) — the length of the string s and the number of queries correspondingly. The second line contains n lucky digits without spaces — Petya's initial string. Next m lines contain queries in the form described in the statement.

Output

For each query count print an answer on a single line.

Examples
input
2 3
47
count
switch 1 2
count
output
2
1
input
3 5
747
count
switch 1 1
count
switch 1 3
count
output
2
3
2
Note

In the first sample the chronology of string s after some operations are fulfilled is as follows (the sought maximum subsequence is marked with bold):

  1. 47
  2. 74
  3. 74
In the second sample:
  1. 747
  2. 447
  3. 447
  4. 774
  5. 774


0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

poj3264 线段树维护最大值最小值

用线段树来维护区间的最大值最小值   建好线段树,就可以针对查询来查出最大值最小值  从而求出其差值 #include #include #include #include #include #include #include #inclu...
  • jk13171217
  • jk13171217
  • 2015-08-04 16:35
  • 248

Codeforces-785E-Anton and Permutation(分块区间查询,动态查询[l,r]内小于某个值的元素个数)

题目链接:Codeforces-785E-Anton and Permutation当交换a[l]和a[r]时。讨论区间为(l,r),那么ans=ans+区间内比a[r]小的个数−区间内比a[l]小的个数+区间内比a[l]大的个数−区间内比a[r]大的个数+(a[l]>a[r]?1:−1)an...
  • jinglinxiao
  • jinglinxiao
  • 2017-03-26 18:54
  • 395

区间合并算法

需求:给定多个连续的区间,将区间进行合并,输出一个或多个没有交集的连续区间。 支持泛型,可以用数值或者字符串表示区间(实际上是Comparable接口)。 环境:jdk1.8 package cn.howso.deeplan.psi.vague.utils.interval; impor...
  • zhoujiaping123
  • zhoujiaping123
  • 2017-06-29 13:24
  • 337

区间覆盖与合并

问题最近打google的apactest,遇到一个经典的(但我不熟的)问题——给你一堆整数区间(比如[1, 3], [2, 6], [8, 10]),问它们合并后是怎样的? 比如上述三个区间合并后就变成:[1, 6], [8, 10]。这个问题在leetcode上的难度评级是Hard,简直亮瞎啊,...
  • Jacketinsysu
  • Jacketinsysu
  • 2016-08-30 11:31
  • 1142

hdu4348 To the moon(区间修改,区间查询的主席树)

每个时间建一棵线段树,这样就很好回到过去的某一版本了。然后区间修改就像线段树那样,但是不能下放懒标记,因为你的左右子树可能是公用的历史版本,会出锅。你只能记成绝对标记。每次在路径上累加懒标记。还要注意区间长度。
  • Icefox_zhx
  • Icefox_zhx
  • 2017-12-01 11:52
  • 66

【LeetCode-面试算法经典-Java实现】【056-Merge Intervals(区间合并)】

【056-Merge Intervals(区间合并)】【LeetCode-面试算法经典-Java实现】【所有题目目录索引】原题  Given a collection of intervals, merge all overlapping intervals.   For example,   ...
  • DERRANTCM
  • DERRANTCM
  • 2015-07-29 06:51
  • 3270

简化SQL式计算之区间合并

在数据库应用开发中,我们经常需要面对复杂的SQL式计算,区间合并就是其中一种,比如进行不重复时间段汇总,或将重叠的时间段合并等计算。由于SQL集合无序,实现时需要采用递归的方式实现,而对于递归函数不足的数据库实现起来则更加困难。除了递归,SQL实现时还要依赖多层子查询嵌套问题,SQL语句过为冗长使得...
  • u012388497
  • u012388497
  • 2015-09-08 08:35
  • 588

Openjudge NOI题库2.4基本算法之分治 7620:区间合并

 总时间限制: 1000ms 内存限制: 65536kB 描述 给定 n 个闭区间 [ai; bi],其中i=1,2,...,n。任意两个相邻或相交的闭区间可以合并为一个闭区间。例如,[1;2] 和 [2;3] 可以合并为 [1;3],[1;3] 和 [2;4] 可以合并为 [1;4],但...
  • EnemyGodlike
  • EnemyGodlike
  • 2017-01-23 17:55
  • 748

动态规划学习系列——区间DP(一)

学习一个算法,还是从题目开始比较好,我们就从一道经典例题开始: wikioi 1048 石子归并 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得...
  • fuyukai
  • fuyukai
  • 2015-02-13 17:13
  • 811

treap分离合并 区间操作 poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 53831   Accepted: 16158 Case Time Limit...
  • u012358934
  • u012358934
  • 2014-03-06 15:29
  • 1657
    个人资料
    • 访问:182777次
    • 积分:7625
    • 等级:
    • 排名:第3287名
    • 原创:602篇
    • 转载:2篇
    • 译文:0篇
    • 评论:36条
    文章分类
    最新评论