【12.6】日记

12.6日记

线段树

  1. HDU1540:单点修改+单点所在最长连续区间

思路:昨天用了set(平衡树)做的,发现简单的一批,还是学了一下线段树的做法。不过学完了之后发现,确实用线段树还是很有必要的,如果是区间修改的话,平衡树就挂了,就只能用线段树来处理了。更何况还有可能有区间所在最长连续区间之类的题目。

构造:每个节点存放4个值,lm记录当前区间,以左端点为左端点的最长1区间的长度,rm记录当前区间,以右端点为右端点的最长1区间的长度,mm记录当前区间最长1区间的长度,col是辅助数组,如果当前区间全都是1,那么col=1,如果当前区间全都是0,那么col=0,否则col=-1。显然col可以直接用mm来代替,所以简单写的话存放3个值就可以。

pushup:(核心操作)

  1. lm:如果左儿子全为1,则lm[id]=lm[id*2]+lm[id*2+1](因为会扩展到右区间),否则lm[id]=lm[id*2]
  2. rm:如果右儿子全为1,则rm[id]=rm[id*2]+rm[id*2+1](因为会扩展到右区间),否则rm[id]=rm[id*2+1]
  3. mm:三个值的最大值:mm[id]=max(mm[id*2],mm[id*2+1],rm[id*2]+lm[id*2+1])
  4. col:用mm的值去推。如果mm=0则col=0,如果mm=r-l+1则col=1,否则col=-1。

此处没有pushdown操作。

operate:直接暴力单点修改,记得pushup

query:比较复杂。核心思想是:检验目标点是否可以被横跨两个儿子的区间所包含,如果能,就直接求得答案,否则递归。

具体实现如下,首先判断目标点pos在左儿子还是右儿子。如果在左儿子,那么判断rm[id*2]是否可能包含pos,如果能包含,则return rm[id*2]+lm[id*2+1]。否则就递归左儿子。如果在右儿子,那么判断lm[id*2+1]是否可能包含pos,如果能包含,则return rm[id*2]+lm[id*2+1]。否则就递归右儿子。

用贪心容易知道,如果能包含的话,直接返回的长度,就是最长的区间。

#include<bits/stdc++.h>
#define mid (l+r)/2
using namespace std;
const int M=5e4+20;
int lm[4*M],rm[4*M],mm[4*M],col[4*M];
inline void pushup(int id,int l,int r){
    if (col[id*2]==1)
        lm[id]=lm[id*2]+lm[id*2+1];
    else
        lm[id]=lm[id*2];
    if (col[id*2+1]==1)
        rm[id]=rm[id*2+1]+rm[id*2];
    else
        rm[id]=rm[id*2+1];
    mm[id]=max(max(mm[id*2],mm[id*2+1]),rm[id*2]+lm[id*2+1]);
    if (mm[id]==0)
        col[id]=0;
    else if (mm[id]==r-l+1)
        col[id]=1;
    else
        col[id]=-1;
}
void build(int id,int l,int r){
    col[id]=1;
    lm[id]=rm[id]=mm[id]=r-l+1;
    if (l==r)
        return;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    pushup(id,l,r);
}
void operate(int id,int l,int r,int pos,int x){
    if (l==r){
        if (x)
            lm[id]=rm[id]=mm[id]=col[id]=1;
        else
            lm[id]=rm[id]=mm[id]=col[id]=0;
        return;
    }
    if(pos<=mid)
        operate(id*2,l,mid,pos,x);
    else
        operate(id*2+1,mid+1,r,pos,x);
    pushup(id,l,r);
}
int query(int id,int l,int r,int pos){
    if(l==r)
        return mm[id];
    if (pos<=mid){
        if (pos+rm[id*2]>mid)
            return rm[id*2]+lm[id*2+1];
        else
            return query(id*2,l,mid,pos);
    }
    else{
        if (mid+lm[id*2+1]>=pos)
            return rm[id*2]+lm[id*2+1];
        else
            return query(id*2+1,mid+1,r,pos);
    }
}
stack<int> stk;
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        build(1,1,n);
        for(int i=1;i<=m;++i){
            char s[2];
            int x;
            scanf("%s",s);
            if (s[0]=='R')
                operate(1,1,n,stk.top(),1),stk.pop();
            else{
                scanf("%d",&x);
                if (s[0]=='D')
                    operate(1,1,n,x,0),stk.push(x);
                else
                    printf("%d\n",query(1,1,n,x));
            }
        }
    }
    return 0;
}

总结

最近实在是太忙了,我哭了,赶紧学习。还有一个周,拼了!

原文地址:https://www.cnblogs.com/diorvh/p/12001358.html

时间: 2024-08-11 13:19:04

【12.6】日记的相关文章

2015年3月12日-日记

今天突然感觉有点压力.亮经理突然发给了我几个链接~关于电机运动控制的资料,包括淘宝上的链接,可以购买网上的源码来二次开发,看这源码一套就要1600块钱~一看就是有钱淫啊~说是给我开发用的~哎,突然觉得过不久我就要转职去工艺部了~这一点还不太敢想,要是工资能有多一点那我当然可以接受了.感觉职业道路上突然面对着两种选择:1.专研数控机床.2.继续嵌入式,做做小项目.如果转去工艺部,相信这辈子就是跟数控机床打交道了,但是偶尔也会有点其他自动化设备要做吧..自己以后要发展成为什么样的职业呢?不太懂,原本

【日记】12.4

12.4日记 CDQ分治 HDU1541:给定一些(a,b),定义(a,b)的等级为满足(a2<=a&&b2<=b)的(a2,b2)的个数.输出等级为0-n-1的星星个数. 二维偏序裸题.第一位排好序,第二维树状数组即可. 注意:树状数组不可以处理下标为0的情况,因此需要先+1.或者就直接离散化.离散化的时候,注意int len=unique(a+1,a+n+1)-a-1; 线段树 HDU4578:区间加减+区间乘+区间修改+区间询问一次二次三次方和. 我tm哭了,debug了

Hadoop日记系列目录

下面是Hadoop日记系列的目录,由于目前时间不是很充裕,以后的更新的速度会变慢,会按照一星期发布一期的原则进行,希望能和大家相互学习.交流. 目录安排 1>  Hadoop日记Day1---Hadoop介绍 2>  Hadoop日记Day2---虚拟机中搭建Linux 3>  Hadoop日记Day3---Hadoop的伪分布式安装 4>  Hadoop日记Day4---去除HADOOP_HOME is deprecated 5>  Hadoop日记Day5---HDFS介

推理小说

1.年龄 我搭上了一列特快车,大概在还差10分就午夜12点的时候,在中途站有一名男子也上了列车,他在车门关闭后,像是突然回复意识一般,开始左右环视着周遭乘客的脸. "恕我愚昧,请问您今年28岁吗?"他如此的向我问道,"是的,不过您怎么知道呢?" 我如此反问他,但被他无视,只是自顾自的和别人说话. "您今年45岁吧?" "是没错." "您是62岁吗?" "你怎么知道的?" 一直和看似不相识

最短的恐怖推理故事

悬疑恐怖故事,你看懂了第几个.没有唯一答案,有理就是正确的.欢迎分享~ 以下内容转自网络,仅供娱乐,切勿太当真! 1.年龄 我搭上了一列特快车,大概在还差10分就午夜12点的时候,在中途站有一名男子也上了列车,他在车门关闭后,像是突然回复意识一般,开始左右环视着周遭乘客的脸. "恕我愚昧,请问您今年28岁吗?"他如此的向我问道,"是的,不过您怎么知道呢?" 我如此反问他,但被他无视,只是自顾自的和别人说话. "您今年45岁吧?" "是没

vc编程中的20点小笔记

机器学习是一项经验技能,经验越多越好.在项目建立的过程中,实践是掌握机器学习的最佳手段.在实践过程中,通过实际操作加深对分类和回归问题的每一个步骤的理解,达到学习机器学习的目的. 预测模型项目模板不能只通过阅读来掌握机器学习的技能,需要进行大量的练习.本文将介绍一个通用的机器学习的项目模板,创建这个模板总共有六个步骤.通过本文将学到: 端到端地预测(分类与回归)模型的项目结构. 如何将前面学到的内容引入到项目中. 如何通过这个项目模板来得到一个高准确度的模板. 副诼匚盼胁臼匾膊讶赖期放判鼻懒合谖

小白日记12:kali渗透测试之服务扫描(二)-SMB扫描

SMB扫描 Server Message Block 协议.与其他标准的TCP/IP协议不同,SMB协议是一种复杂的协议,因为随着Windows计算机的开发,越来越多的功能被加入到协议中去了,很难区分哪些概念和功能应该属于Windows操作系统本身,哪些概念应该属于SMB 协议.因为该协议很复杂,所以是微软历史上出现安全问题最多的协议. 1.Nmap 最简单的方法:扫描其固定开放的端口139,445,但是无法准确判断其为windows系统 [email protected]:~# <strong

OpenGL学习日记-2014.12.21--光照

o(╯□╰)o深患中度拖延症,也是从开始写这篇笔记到结束居然用了一个月...虽然中间是发生了不少事,不过明明就有无数机会可以完成,就是拖着没写代码,各种借口...面对如此拖延症该如何是好QAQ 正文: 突然觉得这些日记写着写着就没什么意思...只是简单梳理一下书中的内容,没经过很多的思考,可不写心里更虚,怕自己几天就把看的书忘了.对于很多概念,都由于没有好好去写代码验证,而理解流于表面.对于光照这章也是下决心细细琢磨一番(现在才下的决心o(╯□╰)o),毕竟这很重要. 一.光照和颜色密切相关,光

AC日记——计算2的N次方 openjudge 1.6 12

12:计算2的N次方 总时间限制:  1000ms 内存限制:  65536kB 描述 任意给定一个正整数N(N<=100),计算2的n次方的值. 输入 输入一个正整数N. 输出 输出2的N次方的值. 样例输入 5 样例输出 32 提示 高精度计算 思路: 模拟: 来,上代码: #include<cstdio> using namespace std; int n; char s[101]; int main() { s[0]=1; scanf("%d",&n