CF145E Lucky Queries

英文题面不放了,直接上翻译:

题目描述

给你n个数,每个数是4或者7,给你m个任务完成

switch l r 把[l,r]位置的4换成7,7换成4

count 计算n个数的最长不下降子序列的长度

N个数的不下降子序列是这n个数移除掉0个或者若干个位置的数,并且满足从第2个数开始每一个数不小于前一个数的大小。

输入格式

第一行n,m

第二行n个数字

接下来m行每行一个命令

输出格式

对于每一个count的命令,输出n个数的最长不下降子序的长度

输入输出样例

输入样例#1:

2 3
47
count
switch 1 2
count
输出样例#1:

2
1
输入样例#2:

3 5
747
count
switch 1 1
count
switch 1 3
count
输出样例#2:

2
3
2

题解Here!

看到区间问题,线段树之类的肯定没得跑。
当然将$4,7$转成$0,1$应该都能想到。
不过怎样区间翻转是一个问题。
我们记录最长不上升子序列的长度和最长不下降子序列的长度,然后分别维护即可。
区间翻转的时候翻转一下就好。
那,维护怎么办?
其实最长不下降子序列只有一种情况:前面若干个$4$,后面若干个$7$。
那我们只要搞出分界点就好。
这里的分界点指的是最后一个$4$的位置。
而分界点只会在三个地方:左儿子区间$[l,mid-1]$中,$mid$,右儿子区间$[mid+1,r]$中。
于是分别计算长度,取最大值就好。
最长不上升子序列同理。
复杂度$O(m\log_2n)$。
代码还是挺好码的。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define FOUR(x) a[x].four
#define SEVEN(x) a[x].seven
#define SIGN(x) a[x].c
#define UPON(x) a[x].upon
#define DOWN(x) a[x].down
#define LSIDE(x) a[x].l
#define RSIDE(x) a[x].r
#define WIDTH(x) (RSIDE(x)-LSIDE(x)+1)
#define MAXN 1000010
using namespace std;
int n,m;
char ch[MAXN];
struct Segment_Tree{
int seven,four,c,upon,down;
int l,r;
}a[MAXN<<2];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void pushup(int rt){
FOUR(rt)=FOUR(LSON)+FOUR(RSON);
SEVEN(rt)=SEVEN(LSON)+SEVEN(RSON);
UPON(rt)=max(FOUR(LSON)+SEVEN(RSON),max(FOUR(LSON)+UPON(RSON),UPON(LSON)+SEVEN(RSON)));
DOWN(rt)=max(SEVEN(LSON)+FOUR(RSON),max(SEVEN(LSON)+DOWN(RSON),DOWN(LSON)+FOUR(RSON)));
}
inline void pushdown(int rt){
if(!SIGN(rt)||LSIDE(rt)==RSIDE(rt))return;
SIGN(LSON)^=1;
swap(FOUR(LSON),SEVEN(LSON));
swap(UPON(LSON),DOWN(LSON));
SIGN(RSON)^=1;
swap(FOUR(RSON),SEVEN(RSON));
swap(UPON(RSON),DOWN(RSON));
SIGN(rt)=0;
}
void buildtree(int l,int r,int rt){
LSIDE(rt)=l;RSIDE(rt)=r;SIGN(rt)=0;
if(l==r){
FOUR(rt)=(ch[l]=='4');
SEVEN(rt)=(FOUR(rt)^1);
UPON(rt)=DOWN(rt)=1;
return;
}
int mid=l+r>>1;
buildtree(l,mid,LSON);
buildtree(mid+1,r,RSON);
pushup(rt);
}
void update(int l,int r,int rt){
if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
SIGN(rt)^=1;
swap(FOUR(rt),SEVEN(rt));
swap(UPON(rt),DOWN(rt));
return;
}
pushdown(rt);
int mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)update(l,r,LSON);
if(mid<r)update(l,r,RSON);
pushup(rt);
}
void work(){
int l,r;
while(m--){
scanf("%s",ch);
if(ch[0]=='s'){
l=read();r=read();
update(l,r,1);
}
else printf("%d\n",UPON(1));
}
}
void init(){
n=read();m=read();scanf("%s",ch+1);
buildtree(1,n,1);
}
int main(){
init();
work();
return 0;
}

CF145E Lucky Queries的更多相关文章

  1. 数据结构(线段树):CodeForces 145E Lucky Queries

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

  2. Codeforces 145E Lucky Queries 线段树

    Lucky Queries 感觉是很简单的区间合并, 但是好像我写的比较麻烦. #include<bits/stdc++.h> #define LL long long #define f ...

  3. Codeforces Round #104 (Div. 1)

    A.Lucky Conversion 题意 给定两个长度为 \(N(N \le 10^5)\) 且由4和7构成的 \(a, b\)串 对 \(a\) 可以有两种操作: 交换两个位置的字符; 改变一个位 ...

  4. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  5. spoj gss2 : Can you answer these queries II 离线&&线段树

    1557. Can you answer these queries II Problem code: GSS2 Being a completist and a simplist, kid Yang ...

  6. SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

    GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot ...

  7. 实践 HTML5 的 CSS3 Media Queries

    先来介绍下 media,确切的说应该是 CSS media queries(CSS 媒体查询),媒体查询包含了一个媒体类型和至少一个使用如宽度.高度和颜色等媒体属性来限制样式表范围的表达式.CSS3 ...

  8. lucky 的 时光助理(2)

    lucky小姐说:昨天晚上他喝醉了,发消息说他想我了,说他后悔了. 我很惊讶. 我问lucky:你们很久都没有联系, 突然说... 你怎么想. 没错,'他'就是lucky的前男友. lucky看着我, ...

  9. lucky 的 时光助理

    2017年的lucky小姐,厌倦了现在的工作,她觉得这些的工作对于她而言不具备挑战性,她在迷茫春节过后该如何选择, 这里是距她走出校门整整一年的时光. lucky小姐从开发走向了实施,目的是想周游这个 ...

随机推荐

  1. 编写C函数的技术-《lua程序设计》 27章 学习

    1.数组操作 void lua_rawgeti(lua_State * L ,int index,int key) void lua_rewseti(lua_State * L,int index,i ...

  2. 数据库面试题.net

    1.ADO.net中常用的对象 connection, command, sqladapter, dataset, dataview. 2.net中读写数据库要用到哪些类 DataSet数据存储 Da ...

  3. 通过windows自带的系统监视器来查看IIS并发连接数(perfmon.msc)

    如果要查看IIS连接数,最简单方便的方法是通过“网站统计”来查看,“网站统计”的当前在线人数可以认为是当前IIS连接数.然而,“网站统计”的当前在线人数统计时间较长,一般为10分钟或15分钟,再加上统 ...

  4. WCF RIA Services使用详解(转载)

    理解领域服务和领域操作 本文目录: 3.1 WCF Ria Services简介 3.1.1 什么是WCF Ria Services 3.1.2 WCF Ria Services如何生成客户端代码 3 ...

  5. c++ [wrong]simple "Garbage Collector"

    In fact, Ptr alone can accomplish the task mentioned below. Implementation see Ptr.h, main2.cpp. In ...

  6. Flex读取txt文件里的内容报错

    Flex读取txt文件里的内容 1.详细错误例如以下 2.错误原因 读取文件不存在 var file:File = new File(File.applicationDirectory.nativeP ...

  7. active mq 配置

    <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame s ...

  8. vCenter初始化数据中心和集群

    接着上一次的文档"7.vCeenter部署流程2",vcenter软件已经安装在2008上了,同时win2008上的和vmware相关的服务都已经启动,这里一定要检查以下: 打开服 ...

  9. Nginx区分PC或手机访问不同网站

    近几年来,随着手机和pad的普及,越来越多的用户选择使用移动客户端访问网站,而为了获取更好的用户体验,就需要针对不同的设备显示出最合适的匹配,这样就是近年来流行的“响应式web设计”. 响应式web设 ...

  10. java 定时器

    import java.io.IOException; import java.util.Timer; public class TimerTest { public static void main ...