Codeforce E. Lucky Queries 线段树实践
来源:互联网 发布:手机测经纬度软件 编辑:程序博客网 时间:2024/05/22 04:39
E. Lucky Queries
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 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.
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.
For each query count print an answer on a single line.
2 347countswitch 1 2count
21
本题关键难点是线段树的动态更新,需要设置一个Lazy标志,就是不需要每次更新所有点,而是等到下次需要查询到这个点的时候,更新这个点的两个孩子节点。
其中的逻辑关系,需要好好研究研究代码吧。 没搞清其中的逻辑,还是十分有难度的。
线段树本题就两个点了:
1 二分法操作树
2 Lazy标志动态更新区间
#include <stdio.h>#include <string>#include <iostream>#include <algorithm>#include <cmath>using namespace std;class LuckyQueries{int n, tSize;char *str;struct Node{int L4, L7, L47, L74;bool lazy;};Node *segTree;void updateNode(int id, int left, int right){segTree[id].L4 = segTree[left].L4 + segTree[right].L4;segTree[id].L7 = segTree[left].L7 + segTree[right].L7;int a = segTree[left].L47 + segTree[right].L7;int b = segTree[left].L4 + segTree[right].L47;segTree[id].L47 = max(a, b);a = segTree[left].L74 + segTree[right].L4;b = segTree[left].L7 + segTree[right].L74;segTree[id].L74 = max(a, b);segTree[id].lazy = false;}void conHelper(int low, int up, int id = 0){if (low == up){if (str[low] == '4') {segTree[id].L4 = 1, segTree[id].L7 = 0;segTree[id].L47 = 1, segTree[id].L74 = 0;}else{segTree[id].L4 = 0, segTree[id].L7 = 1;segTree[id].L47 = 0, segTree[id].L74 = 1;}segTree[id].lazy = false;return ;}int mid = low + ((up-low)>>1);int left = id*2+1;int right = id*2+2;conHelper(low, mid, left);conHelper(mid+1, up, right);updateNode(id, left, right);}void conTree(){int h = (int) ceil((double)log(double(n))/log(2.0)) + 1;tSize = (int) pow(2.0, double(h)) - 1;segTree = (Node *) malloc(sizeof(Node) * tSize);conHelper(0, n-1);}inline int getLongestIncease(){return max(segTree[0].L4, max(segTree[0].L47, segTree[0].L7));}void invert(int root){segTree[root].lazy = !segTree[root].lazy;swap(segTree[root].L4, segTree[root].L7);swap(segTree[root].L47, segTree[root].L74);}void updateTree(const int low, const int up, int tLow, int tUp, int root = 0){if (tUp < low || up < tLow)//错写||成&&{return ;}if (low <= tLow && tUp <= up){invert(root);return ;}int tMid = tLow + ((tUp-tLow)>>1);int left = root * 2 + 1;int right = root * 2 + 2;if (segTree[root].lazy){segTree[root].lazy = false;invert(left);invert(right);}updateTree(low, up, tLow, tMid, left);updateTree(low, up, tMid+1, tUp, right);updateNode(root, left, right);}public:LuckyQueries(){int m;scanf("%d %d", &n, &m);getchar();//别忘记了去掉一个换行符str = (char *) malloc(sizeof(char) * (n+1));gets(str);conTree();char command[8];for (int i = 0; i < m; i++){char c = getchar();if ('c' == c){printf("%d\n", getLongestIncease());gets(command);//gets一行}else{while (c != ' ') c = getchar();int low, up;scanf("%d %d", &low, &up);updateTree(low-1, up-1, 0, n-1);if (i+1 != m) getchar();}}}~LuckyQueries(){if (str) free(str);if (segTree) free(segTree);}};
- Codeforce E. Lucky Queries 线段树实践
- Cf Round #104 (Div. 1) E Lucky Queries 线段树
- 线段数练习一: CF145E E. Lucky Queries
- codeforces 145E - Lucky Queries
- codeforces 145E Lucky Queries
- codeforce 6E 线段树+枚举
- CF 256E Lucky Arrays(线段树+DP)
- CF 256E Lucky Arrarys 【线段树+DP】
- codeforces 266E More Queries to Array 线段树
- CF 266E More Queries to Array...(线段树)
- 【CodeForces】266E More Queries to Array... 线段树
- CodeForces 266E More Queries to Array... 线段树
- Codeforces Round #104 (Div. 1) E Lucky Queries
- Codeforce-242E-XOR on Segment(线段树区间更新)
- CodeForces 266E - More Queries to Array 拆解求和公式,线段树区间更新与求和
- CodeForces 266E More Queries to Array...(线段树+式子展开)
- codeforces817F MEX Queries -- 线段树
- LightOJ 1097 - Lucky Number(线段树)
- Android实现计算器的两种方式
- 结构型模式专题总结
- UVa 11488 - Hyper Prefix Sets
- Java颜色选择器
- 同余定理
- Codeforce E. Lucky Queries 线段树实践
- nginx源码分析--使用GDB调试
- Python边学边用
- 浅显理解 Python 闭包
- 修改 mysql 密码
- 我的软考之路(九)——总结篇
- 第二学期第十二周项目1--长颈鹿类对动物类的继承
- 第13周 点圆关系
- C++箭头(->)运算符的重载