• Codeforces Round #104 (Div. 1) E. Lucky Queries 线段树


    链接:

    http://codeforces.com/contest/145/problem/E

    题意:

    维护一个只有数字4和7的数列,以下有两种操作: 

    1.将[l,r]区间4变为7,7变为4。 

    2.询问全局最长不下降子序列的长度。 

    输出所有2操作的答案

    题解:

    线段树维护。 

    维护四个信息: 

    1.区间4的个数。 

    2.区间7的个数。 

    3.区间不降子序列的长度。 

    4.区间不升子序列的长度。

    具体更新的看代码

    代码:

    31 int n, m;
    32 string s;
    33 struct Node {
    34     int f, s, fs, sf, rev;
    35 }Tree[MAXN << 2];
    36 
    37 void pushup(int rt) {
    38     Tree[rt].f = Tree[rt << 1].f + Tree[rt << 1 | 1].f;
    39     Tree[rt].s = Tree[rt << 1].s + Tree[rt << 1 | 1].s;
    40     Tree[rt].fs = max(Tree[rt << 1].f + Tree[rt << 1 | 1].fs, Tree[rt << 1].fs + Tree[rt << 1 | 1].s);
    41     Tree[rt].sf = max(Tree[rt << 1].s + Tree[rt << 1 | 1].sf, Tree[rt << 1].sf + Tree[rt << 1 | 1].f);
    42 }
    43 
    44 void pushdown(int rt) {
    45     if (Tree[rt].rev) {
    46         swap(Tree[rt << 1].f, Tree[rt << 1].s);
    47         swap(Tree[rt << 1 | 1].f, Tree[rt << 1 | 1].s);
    48         swap(Tree[rt << 1].sf, Tree[rt << 1].fs);
    49         swap(Tree[rt << 1 | 1].sf, Tree[rt << 1 | 1].fs);
    50         Tree[rt << 1].rev ^= 1;
    51         Tree[rt << 1 | 1].rev ^= 1;
    52         Tree[rt].rev = 0;
    53     }
    54 }
    55 
    56 void build(int l, int r, int rt) {
    57     if (l == r) {
    58         if (s[l - 1] == '4') Tree[rt].f = 1;
    59         else Tree[rt].s = 1;
    60         Tree[rt].fs = Tree[rt].sf = 1;
    61         return;
    62     }
    63     int m = (l + r) >> 1;
    64     build(lson);
    65     build(rson);
    66     pushup(rt);
    67 }
    68 
    69 void update(int L, int R, int l, int r, int rt) {
    70     if (L <= l && r <= R) {
    71         Tree[rt].rev ^= 1;
    72         swap(Tree[rt].f, Tree[rt].s);
    73         swap(Tree[rt].fs, Tree[rt].sf);
    74         return;
    75     }
    76     pushdown(rt);
    77     int m = (l + r) >> 1;
    78     if (L <= m) update(L, R, lson);
    79     if (R > m) update(L, R, rson);
    80     pushup(rt);
    81 }
    82 
    83 int main() {
    84     ios::sync_with_stdio(false), cin.tie(0);
    85     cin >> n >> m >> s;
    86     build(1, n, 1);
    87     while (m--) {
    88         string s;
    89         cin >> s;
    90         if (s == "switch") {
    91             int l, r;
    92             cin >> l >> r;
    93             update(l, r, 1, n, 1);
    94         }
    95         else cout << Tree[1].fs << endl;
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    『C#基础』数据库死锁笔记
    『C#基础』IIS的权限问题
    『C#基础』调用CMD的一个小工具
    『C#基础』获取系统图标的一个操作类
    『程序人生』其实,做软件与打游戏是一样一样的……
    『C#基础』C#调用存储过程
    『Linux』Arch Linux与VirtualBox的结合
    sql server 触发器简单学习
    用触发器替换原来的insert
    食物增肥一方
  • 原文地址:https://www.cnblogs.com/baocong/p/7384692.html
Copyright © 2020-2023  润新知