zoukankan      html  css  js  c++  java
  • Lucky Queries (线段树的区间合并)

    Lucky Queries

     CodeForces - 145E 

      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 47, 744, 4 are lucky and 5, 17, 467 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 7and each digit 7 is replaced with (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

    题意:n代表字符串的长度,m代表操作的次数。两种操作:count:输出该字符串中非递减子序列的最大长度(子序列不是子串,不需要连续)switch:表示将从l 到 r的所有字符改变,4变成7,7变成4

    题解:

    在线段树中维护一下值:

    len4表示全是4的最长子序列。

    len7表示全是7的最长子序列。

    len47表示以4开头以7结尾的最长子序列。

    对于操作2,因为反转之后对len4,len7,len47的值影响较大(主要还是len47),所以一般对这样的题都是直接维护两个值,一个是当前的,一个是反转后的,当进行反转操作时再交换就好了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int maxn=1e6+10;
      7 int n,m; 
      8     char s[maxn];
      9     char op[20];
     10 struct node{
     11     int l;
     12     int r;
     13     int laz;
     14     int len4[2],len7[2],len47[2];
     15 }e[maxn<<2];
     16 void pushup(int cur,int c)
     17 {
     18     e[cur].len4[c]=e[cur<<1].len4[c]+e[cur<<1|1].len4[c];//4的长度为左子树4的长度+右子树4的长度 
     19     e[cur].len7[c]=e[cur<<1].len7[c]+e[cur<<1|1].len7[c];
     20     int temp=e[cur<<1].len4[c]+max(e[cur<<1|1].len7[c],e[cur<<1|1].len47[c]);//len47=左子树len4+右子树len47 左子树len4+右子树len7  左子树len47+右子树len7中取较大的 
     21     e[cur].len47[c]=max(temp,e[cur<<1].len47[c]+e[cur<<1|1].len7[c]);
     22     return;
     23 }
     24 void change(int cur)
     25 {
     26     e[cur].laz^=1;
     27     swap(e[cur].len4[0],e[cur].len4[1]);
     28     swap(e[cur].len7[0],e[cur].len7[1]);
     29     swap(e[cur].len47[0],e[cur].len47[1]);
     30 return;
     31 }
     32 void pushdown(int cur)
     33 {
     34     if(e[cur].laz)
     35     {
     36         //int mid=(e[cur].l+e[cur].r)/2;
     37         change(cur<<1);
     38         change(cur<<1|1);
     39         e[cur].laz=0;
     40     }
     41     return;
     42 }
     43 void build(int l,int r,int cur)
     44 {
     45     e[cur].l=l;
     46     e[cur].r=r;
     47     e[cur].laz=0;
     48     if(l==r)
     49     {
     50         if(s[l]=='4')
     51         {
     52             e[cur].len4[0]=e[cur].len7[1]=1;//e[cur].len4[0]代表没改变前len4为1,e[cur].len7[1]=1表示如果把4的值改变为7,那么len7为1 len数组中0代表没改变,1代表改变后的值 
     53             e[cur].len4[1]=e[cur].len7[0]=0; 
     54         }
     55         else
     56         {
     57             e[cur].len7[0]=e[cur].len4[1]=1;
     58             e[cur].len7[1]=e[cur].len4[0]=0;
     59         }
     60         e[cur].len47[0]=e[cur].len47[1]=0;
     61         return;
     62     }
     63     int mid=(l+r)/2;
     64     build(l,mid,cur<<1);
     65     build(mid+1,r,cur<<1|1);
     66     pushup(cur,0);
     67     pushup(cur,1);
     68 }
     69 void update(int pl,int pr,int cur)
     70 {
     71     if(pl<=e[cur].l&&e[cur].r<=pr)
     72     {
     73         change(cur);
     74         return;
     75     }
     76     pushdown(cur);
     77     int mid=(e[cur].l+e[cur].r)/2;
     78     if(pl<=mid)
     79         update(pl,pr,cur<<1);
     80     if(pr>mid)
     81         update(pl,pr,cur<<1|1);
     82     pushup(cur,0);
     83     pushup(cur,1);
     84 }
     85 int main()
     86 {
     87     scanf("%d%d",&n,&m);
     88     scanf("%s",s+1);
     89     build(1,n,1);
     90     while(m--)
     91     {
     92         int x,y;
     93         scanf("%s",op);
     94         if(op[0]=='s')
     95         {
     96             scanf("%d%d",&x,&y);
     97             update(x,y,1);
     98         }
     99         else
    100         {
    101             printf("%d
    ",max(e[1].len4[0],max(e[1].len47[0],e[1].len7[0])));
    102         }
    103     }
    104 }
  • 相关阅读:
    golang的reflect
    minium-介绍
    selenium+Node.js在windows下的配置和安装
    Jmeter-逻辑控制器之Switch控制器(Switch Controller)
    Jmeter-逻辑控制器之Foreach
    chrome插件-YSlow 一个使用的web性能测试插件
    jmeter
    Jmeter-从数据库中获取数据并作为变量传输
    Jmeter-无法启动,'findstr'不是内部或外部命令,也不是可运行的程序
    Jmeter-响应结果unicode转成中文显示
  • 原文地址:https://www.cnblogs.com/1013star/p/9600810.html
Copyright © 2011-2022 走看看