zoukankan      html  css  js  c++  java
  • CodeForces 145E Lucky Queries (线段树)

    题意:给定一个47序列,然后有两种操作,

    1.switch l, r 把区间内的4变成7,7变成4

    2.count 计算整个区间的最长的非降序序列长度。

    析:一个很裸的线段树,就是维护几个值,一个是只有4的长度,一个只有7的,一个47都有的,每个都维护正着反着,然后就很简单了。

    在更新时,4和7直接相加就好了,47都有的取个最大值,左边4右边7,左边4,右边47,左边47右边7。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <sstream>
    #define debug() puts("++++");
    #define gcd(a, b) __gcd(a, b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e17;
    const double inf = 0x3f3f3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int dr[] = {-1, 0, 1, 0};
    const int dc[] = {0, 1, 0, -1};
    const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline bool is_in(int r, int c){
      return r >= 0 && r < n && c >= 0 && c < m;
    }
    
    int length4[maxn<<2][2], length7[maxn<<2][2], length[maxn<<2][2];
    bool rev[maxn<<2];
    char s[maxn];
    
    void push_up(int rt){
      int l = rt<<1, r = rt<<1|1;
      for(int i = 0; i < 2; ++i){
        length4[rt][i] = length4[l][i] + length4[r][i];
        length7[rt][i] = length7[l][i] + length7[r][i];
        length[rt][i] = max(length4[l][i]+length[r][i], max(length[l][i]+length7[r][i], length4[l][i]+length7[r][i]));
      }
    }
    
    void rever(int rt){
      swap(length4[rt][0], length4[rt][1]);
      swap(length7[rt][0], length7[rt][1]);
      swap(length[rt][0], length[rt][1]);
      rev[rt] = !rev[rt];
    }
    
    void push_down(int rt){
      if(!rev[rt])  return ;
      rever(rt<<1);
      rever(rt<<1|1);
      rev[rt] = 0;
    }
    
    void build(int l, int r, int rt){
      if(l == r){
        s[l] == '4' ? ++length4[rt][0] : ++length7[rt][0];
        length4[rt][1] = length7[rt][0];
        length7[rt][1] = length4[rt][0];
        return ;
      }
      int m = l + r >> 1;
      build(lson);
      build(rson);
      push_up(rt);
    }
    
    void update(int L, int R, int l, int r, int rt){
      if(L <= l && r <= R){
        rever(rt);
        return ;
      }
      push_down(rt);
      int m = l + r >> 1;
      if(L <= m)  update(L, R, lson);
      if(R > m)   update(L, R, rson);
      push_up(rt);
    }
    
    int query(int rt){
      int ans = max(length4[rt][0], length7[rt][0]);
      return max(ans, length[rt][0]);
    }
    
    int main(){
      scanf("%d %d", &n, &m);
      scanf("%s", s+1);
      build(1, n, 1);
      while(m--){
        scanf("%s", s);
        if(s[0] == 's'){
          int l, r;
          scanf("%d %d", &l, &r);
          update(l, r, 1, n, 1);
        }
        else  printf("%d
    ", query(1));
      }
      return 0;
    }
    

      

  • 相关阅读:
    mysql报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    MD5登陆密码的生成
    15. 3Sum、16. 3Sum Closest和18. 4Sum
    11. Container With Most Water
    8. String to Integer (atoi)
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    几种非线性激活函数介绍
    AI初探1
    AI初探
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/7152669.html
Copyright © 2011-2022 走看看